转载请注明原创出处,谢谢!

最近没有什么实战,准备把JVM知识梳理一遍,先以开发人员的交流来谈谈jvm这块的知识以及重要性,依稀记得2、3年前用solr的时候老是经常oom,提到oom大家应该都不陌生,那个时候也并没有从根本解决oom,由于对jvm不熟悉,只是去百度,到处都是配置jvm参数的,那个时候啥不懂,直接粘贴,但是并没有解决问题,通过这个就告诉我们作为开发人员也需要对jvm很熟悉才行,问题来了,很多人会说我的代码并没有出现oom啊,不需要关注啊,因为不理解不知道重要性,可以回头看看的我的JVM菜鸟进阶高手之路一到九篇系列,可能很多人说还没有到那么高级,不需要理解,我也告诉你也是不对的,且听我慢慢道来。

谈到jvm首先需要谈的是,JAVA虚拟机规范,这个就类似jdbc规范一样,定义了一些规范,oracle有oracle的实现,mysql有mysql的实现,JAVA虚拟机规范也一样,java虚拟机有很多,IBM、Apache Harmony等,每个都有些细节不一样,但是大体符合JAVA虚拟机规范的,由于Oracle收购SUN之后,Oralce主要有JRockit和Hotspot虚拟机了,后来将其进行整合了,不然维护两套麻烦,就和原来的struts1和struts2一样,Oralce主要是以Hotspot来的,把JRockit里面的一些优点也慢慢加入到其中。目前市面上Hotspot占用率是最高的,一般说到JAVA虚拟机基本都是Hotspot虚拟机。JAVA8虚拟机规范地址:http://docs.oracle.com/javase/specs/jvms/se8/html/index.html,按照道理应该去阅读阅读的,虽然java语言与java虚拟机有密切的关系,但是两者是完全不同的内容,像Scala、Clojure、Groovy等语言都是跑在JAVA虚拟机上面的,可以产生各种各样的跨平台语言,除了语言特性不一样,他们可以共享JAVA虚拟机带来的跨平台性、垃圾回收器、以及即使编译(看到这里都应该明白这些的JAVA虚拟机拥有的不是java语言规范定义的,java语言规范地址:http://docs.oracle.com/javase/specs/jls/se8/html/index.html),稍微解释下为什么用JAVA虚拟机就可以做到跨平台呢?依稀记得当时刚刚学习java的时候有句口号“一次编译,到处运行。”Java程序理想上,并不理会真正执行哪个平台,只要知道如何执行于JVM就可以了,至于JVM实际上如何与底层平台沟通,那是JVM自己的事。由于JVM实际上相当于Java程序的操作系统,JVM就负责了Java程序的各种资源管理。

我们要记住两点:

  • JVM就是Java程序的操作系统,JVM的可执行文件就是.class文件。
  • Java虚拟机屏蔽了操作系统之间的差异,但是不同的系统使用的虚拟机不同。

与其他语言相比,Java程序能够做到“编译一次,到处运行”,可见它的跨平台性非常强。其实JVM就是在操作系统层面有抽象了一层虚拟机,这样的好处可以屏蔽底层细节,有每个具体的平台的虚拟机实现即可,但是对外提供的是一致的(比如windows需要安装windows版的jdk,linux需要安装linux版的jdk就是这个原因,jvm虚拟机帮我们屏蔽到了底层的细节)。

一直有一个疑惑,Oracle的jdk和OpenJDK到底有什么关系呢?

Oracle/Sun JDK与OpenJDK的区别和联系如下: - OpenJDK原是SunMicrosystems公司为Java平台构建的Java开发环境(JDK)的开源版本,完全自由,开放源码。Sun Microsystems公司在2006年的JavaOne大会上称将对Java开放源代码,于2009年4月15日正式发布OpenJDK。甲骨文在 2010 年收购SunMicrosystem之后接管了这个项目。

  • oracle/Sun JDK里面包含的JVM是HotSpotVM,HotSpot VM只有非常非常少量的功能没有在OpenJDK里,那部分在Oracle内部的代码库里。这些私有部分都不涉及JVM的核心功能。所以说,Oracle/Sun JDK与OpenJDK其实使用的是同一个代码库。
  • 从一个Oracle内部员工的角度来看,当他要构建OracleJDK时,他同样需要先从http://hg.openjdk.java.NET签出OpenJDK,然后从Oracle内部的代码库签出私有的部分,放在OpenJDK代码下的一个特定目录里,然后构建。值得注意的是,Oracle JDK只发布二进制安装包,而OpenJDK只发布源码。

知道关系之后,其实很多就释然了,其实阿里的jdk就是基于OpenJDK定制的,所以看看OpenJDK对理解JVM很有帮助的,OpenJDK的github地址如下:https://github.com/dmlloyd/openjdk,既然都看见了OpenJDK的源码,那么是否有兴趣编译编译。

用final可以提高性能,为什么呢?

依稀记得以前老师说,用final可以提高性能,为什么呢?由于类的加载机制,关于一个*.class如何加载进来,如何一系列的操作后续会进行介绍,由于类的加载机制会提到一些热替换,热加载,以及阅读tomcat源码的时候可以了解到他是怎么处理加载的,由于final常量在准备阶段就初始化了,而并不是在初始化结点处理的,所以可以提高程序相应效率。
申明为final的情况:

  • 不需要重新赋值的变量,包括类属性、局部变量。
  • 对象参数前面加final,表示不允许修改引用的指向。
  • 类的方法不可以被重写。

由于final关键字,在并发锁的时候,不可变的一些情况锁是无效的

比如锁一个Integer、Double、String等是不行的,你说这些你对JVM不了解能行吗?

JAVA虚拟机对各各数据类型的表示,所以引入了关于,原码,补码,反码等概念,为什么需要补码呢?

补码的好处:

  • 使用补码可以没有任何歧义的表示0。
  • 补码可以很好的参与二进制的运算,补码相加符号位参与运算, 这样就简单很多了。那就可以明白为什么数据溢出的概念了,经常看到

    byte a=(byte)(127+1);
    System.out.println(a);

如果不了解JVM怎么能懂,还有两个值相同的Integer型值进行==比较时:

Integer a=125;
 Integer b=125;
 Integer d=300;
 Integer c=300;
System.out.println(c==d);
System.out.println(a==b);

运行结果为falsetrue?为什么呢? 查看源码: 这儿的IntegerCache有一个静态的Integer数组,在类加载时就将-128 到 127 的Integer对象创建了,并保存在cache数组中, 一旦程序调用valueOf 方法,如果i的值是在-128 到 127 之间就直接在cache缓存数组中去取Integer对象,超出 -128 ~ +127 范围的数字就要即时构建新的Integer对象,可以通过JVM参数 -XX:AutoBoxCacheMax来进行调整。 那么== 和equals的区别,== 是进行地址及值比较,无法对==操作符进行重载,而对于equals方法,Integer里面的equals方法 重写了Object的equals方法,所以,相同类型的包装类对象直接的值比较全部使用equals方法比较,并且能用基本数据类型 就应该用基本数据类型,这些你不了解JVM你那里知道呢?

根据IEEE754定义的浮点数的格式,所以涉及到钱的小数类型必须使用BigDecimal,禁止使用float和double,为什么呢?

不懂JVM可以?后续会讲。

慎用Object的clone方法拷贝对象,深拷贝,浅拷贝。

你不了解jvm模型咋知道呢?还有Object的finalize你不了解JVM怎么理解呢?

对于String的一些操作,String的文章最多。+运算符号

String str = "start";
 for(int i=0; i<100; i++){
     str = str + "hello";
}

反编译出的字节码文件显示每次循环都会new出一个StringBuilder对象,然后进行append操作,最后通过toString方法返回String对象,造成内存资源浪费。

其他

HashMap、ArrayList、StringBuilder等的扩容机制,会浪费空间以及性能(可能存在跨代引用的问题),特别在并发情况下面可能会死锁,后续分享hashMap的cpu 100%情况,所以集合初始化时,尽量指定集合初始值大小,你不了解jvm怎么可以呢?还有很多框架,netty等对外内存(堆外空间),多线程相关ThreadLocal等,还有锁在java虚拟机中的实现优化,你不了解怎么可以呢?
今天仅仅是开场白,后续会有系列基础知识文章出来。大家一起进步。


个人公众号

JVM菜鸟进阶高手之路十(基础知识开场白)的更多相关文章

  1. JVM菜鸟进阶高手之路十四:分析篇

    转载请注明原创出处,谢谢! 题目回顾 JVM菜鸟进阶高手之路十三,问题现象就是相同的代码,jvm参数不一样,表现的现象不一样. private static final int _1MB = 1024 ...

  2. JVM菜鸟进阶高手之路十二(jdk9、JVM方面变化, 蹭热度)

    转载请注明原创出处,谢谢! 经过 4 次跳票,历经曲折的 Java 9 正式版终于发布了!今天看着到处都是jdk9发布了,新特性说明,心想这么好的蹭热度计划能错过嘛,哈哈,所以就发了这篇文章. 目前j ...

  3. JVM菜鸟进阶高手之路十三(等你来战!!!)

    转载请注明原创出处,谢谢! 前几天有个朋友问了我个问题,下面给大家分享下,希望大家积极在评论区进行评论留言,等你来战!!! 先来个趣味题,热身下,引出后面的jvm题目. 地上的影子是那个人的? 地上的 ...

  4. JVM菜鸟进阶高手之路一[z]

    https://mp.weixin.qq.com/s/qD1LFmsOiqZHD8iZX97OfA? 问题现象 代码如下,使用 ParNew + Serial Old 回收器组合与使用 ParNew ...

  5. JVM菜鸟进阶高手之路二(JVM的重要性,Xmn是跟请求量有关。)

    转载请注明原创出处,谢谢! 今天看群聊jvm,通常会问ygc合适吗? 阿飞总结,可能需要2个维度,1.单位时间执行次数,2.执行时间 ps -p pid -o etime 查看下进程的运行时间, 17 ...

  6. JVM菜鸟进阶高手之路一(一次与笨神,阿飞近距离接触修改JVM)

    转载请注明原创出处,谢谢! 今天在JVMPocket群里面看见,阿牛发了一个gc截图,之后ak47截图了特别恐怖,我就觉得好奇,去看看服务情况,截图日志如下 关于jstat命令详情可以参考:https ...

  7. JVM菜鸟进阶高手之路九(解惑)

    转载请注明原创出处,谢谢! 在第八系列最后有些疑惑的地方,后来还是在我坚持不懈不断打扰笨神,阿飞,ak大神等,终于解决了该问题.第八系列地址:http://www.jianshu.com/p/7f7c ...

  8. JVM菜鸟进阶高手之路八(一些细节)

    转载请注明原创出处,谢谢! gc日志问题 查看docker环境的gc日志,发现是下面这种情况,很奇怪,一直怀疑是docker环境那里是否有点问题,并没有怀疑配置,之前物理机上面的gc日志都是正常那种. ...

  9. JVM菜鸟进阶高手之路七(tomcat调优以及tomcat7、8性能对比)

    转载请注明原创出处,谢谢! 因为每个链路都会对其性能造成影响,应该是全链路的修改压测(ak大神经常说全链路!).本次基本就是局域网,所以并没有怎么优化,其实也应该考虑进去的. Linux系统参数层面的 ...

随机推荐

  1. java web方面的面试问题,Spring MVC方面的面试问题,摘自java web轻量级开发面试教程

    本文摘自java web轻量级开发面试教程: https://baike.baidu.com/item/Java%20Web%E8%BD%BB%E9%87%8F%E7%BA%A7%E5%BC%80%E ...

  2. Properties类随笔

    1. 体系介绍 Properties类继承自HashTable,勉强属于集合框架体系一员,键值对形式存储数据,当然键肯定是唯一的,底层哈希表保证键的唯一,此类一般用于表示配置文件. 2. 基本用法 由 ...

  3. XSS分析及如何预防

    XSS分析及如何预防 简单说明: XSS(Cross Site Scripting),又称跨站脚本,XSS的重点不在于跨站点,而是在于脚本的执行.在WEB前端应用日益发展的今天,XSS漏洞尤其容易被开 ...

  4. Web初学-入门和tomcat介绍记录

    一.WEB开发的相关知识 WEB,在英语中web即表示网页的意思,它用于表示Internet主机上供外界访问的资源. Internet上供外界访问的Web资源分为: 静态web资源(如html 页面) ...

  5. python+selenium自动化软件测试(第4章):场景判断与封装

    4.1 显示等待WebDriverWait 前言:在脚本中加入太多的sleep后会影响脚本的执行速度,虽然implicitly_wait()这种隐式等待在一定程度上节省了很多时间.但是一旦页面上某些j ...

  6. 关于用VMware克隆linux系统后,无法联网找不到eth0网卡的问题

    当使用克隆后的虚拟机时发现系统中的网卡eth0没有了,使用ifconfig -a会发现只有eth1.因为系统是克隆过来的,原有的eth0以及ip地址都是原先网卡的,VMware发现已经被占用,就会创建 ...

  7. Swift4.0 Array详解

    数组的介绍 数组(Array)是一串有序的由相同类型元素构成的集合,数组中的集合元素是有序的,可以重复出现.在Swift中数组类型是Array,是一个泛型集合.数组分成:可变数组和不可变数组,分别使用 ...

  8. 一,ESP8266下载和刷固件

    用自己的小板测试...... 安排上呢 一, ESP8266下载和刷固件(Lua开发----体验一下lua开发的魅力所在) 二, 控制一个灯亮灭 三, TCP服务器 四, TCP客户端 五, UDP ...

  9. Linux-grep 命令和find 命令 (6)

    grep与find区别: grep:查找指定目录下过滤文本文件中行数据 find:查找指定目录下文件 grep使用 格式:   grep "text"   *  [选项] 选项: ...

  10. ln命令详解

    ln命令 (全称:link) ln命令用来为文件创建一个连接,类似于Windows的快捷方式,连接类型分为硬连接和软连接(符号连接)两种,默认的连接类型是硬连接.如果要创建符号连接必须使用" ...