性能文章>Jvm菜鸟进阶高手之路一什么是Jvm?>

Jvm菜鸟进阶高手之路一什么是Jvm?原创

6月前
203711

谈到jvm首先需要谈的是,JAVA虚拟机规范:http://docs.oracle.com/javase/specs/jvms/se8/html/index.html,这个就类似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,表示不允许修改引用的指向。
  • 类的方法不可以被重写。

备注: 此处有点错误,今天修改下,更能突出JVM的重要性了。 这个也是今天看见R大回复关于阿里代码规范才发现的。
image1.jpeg
学习了,看看JVM重要吧,今天在此纠正下,我查看新版阿里java代码规范也修改了,新版内容如下:
image2.jpeg
image3.jpeg

由于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);

运行结果为false、true?为什么呢? 查看源码:
image4.jpeg
这儿的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虚拟机中的实现优化,你不了解怎么可以呢?今天仅仅是开场白,后续会有系列基础知识文章出来。大家一起进步。

点赞收藏
分类:标签:
匠心零度
请先登录,查看1条精彩评论吧
快去登录吧,你将获得
  • 浏览更多精彩评论
  • 和开发者讨论交流,共同进步

为你推荐

【全网首发】一次想不到的 Bootstrap 类加载器带来的 Native 内存泄露分析

【全网首发】一次想不到的 Bootstrap 类加载器带来的 Native 内存泄露分析

记一次线上RPC超时故障排查及后续GC调优思路

记一次线上RPC超时故障排查及后续GC调优思路

解读JVM级别本地缓存Caffeine青出于蓝的要诀 —— 缘何会更强、如何去上手

解读JVM级别本地缓存Caffeine青出于蓝的要诀 —— 缘何会更强、如何去上手

【全网首发】一次疑似 JVM Native 内存泄露的问题分析

【全网首发】一次疑似 JVM Native 内存泄露的问题分析

解读JVM级别本地缓存Caffeine青出于蓝的要诀2 —— 弄清楚Caffeine的同步、异步回源方式

解读JVM级别本地缓存Caffeine青出于蓝的要诀2 —— 弄清楚Caffeine的同步、异步回源方式

【全网首发】从源码角度分析一次诡异的类被加载问题

【全网首发】从源码角度分析一次诡异的类被加载问题

1
1