java认知描述_Java技术:JVM的初步认识( 三 )


4.2.5堆
堆和方法区一样(确切来说JVM规范中方法区就是堆的一个逻辑分区),就是一个所有线程共享的,存放对象的区域,也是GC的主要区域.其中的分区分为新生代,老年代.新生代中又可以细分为一个Eden,两个区(From,To).Eden中存放的是通过new 或者方法创建出来的对象,绝大多数都是很短命的.正常情况下经历一次gc之后,存活的对象会转入到其中一个区,然后再经历默认15次的gc,就转入到老年代.这是常规状态下,在区已经满了的情况下,JVM会依据担保机制将一些对象直接放入老年代 。
4.3执行引擎
执行引擎包含即时编译器(JIT)和垃圾回收器(GC),对即时编译器我们简单介绍一下,主要重点在于垃圾回收器.
4.3.1即时编译器(JIT,Just-In-Time )
看到这个东西的存在可能有些人会感到疑问,不是通过javac命令就把我们的java代码编译成字节码文件了吗,这个即时编译器又是干嘛的?
我们需要明确一个概念就是,计算机实际上只认识0和1,这种由0和1组成的命令集称之为"机器码",而且会根据平台不同而有所不同,可读性和可移植性极差.我们的字节码文件包含的并不是机器码,不能由计算机直接运行,而需要JVM"解释"执行.JVM将字节码文件中所写的命令解释成一个个计算机操作命令,再通知计算机进行运算.
JIT并不是Java虚拟机规范定义中规定必须存在的.但它又是JVM性能重要影响因素之一.
在上面的内容里,提到了这么一个名字,它是我们一直使用的这款虚拟机的名称.中文意思是"热点",而 VM的特点之一也就是可以探测并优化热点代码,JIT就是它进行优化的方式.
通过计数以及其他方式,监测到某些方法或者某些代码块执行的频率很高,就会将其编译成为平台相关的机器码,甚至于在保证结果的情况下通过优化执行顺序等方式进行优化,这种机器码的执行效率比解释执行要高出很多.而编译完成后,会通过"栈上替换"等方式进行动态的替换,比如循环执行,循环一次JIT的计数器就+1,到了阈值的时候就开始编译重复执行的代码,同时为了不影响系统的运行,原来的解释执行仍然继续,直到在第N次循环时,编译完成,会在N+1次执行前替换成编译后的机器码执行.
计数器分为两种,一种方法调用计数器,一种回边计数器 。
方法计数器就是用于统计方法的直接调用,而回边计数器用于循环代码的技术 。检测的是频率,所以他们的计数值不会一直累加,而是在一定时间段内叠加,而超过时间段还没有达到阈值,就减半 。这个减半称为"热度衰减",而这个时间段被称为"半衰周期"
但编译成为机器码需要时间,会导致JVM启动时间变长,内存消耗也会增加.所以需要根据实际情况权衡,在启动时附加命令选择执行模式.
纯解释执行模式:-Xint纯编译执行模式:-Xcomp混合模式:默认JIT包含两种编译器, , .
,就是俗称的C1编译器. 也就是俗称的C2编译器.JVM会根据版本及宿主机的硬件性能来自动选择,也可以通过附加命令"-"或者"-"手动选择.
C1编译器编译速度快,但编译后的质量可靠,但性能优化程度不高.
C2编译器编译速度慢,但编译后的性能优化程度很高,有时候会根据性能的监控情况采取"激进"优化.当然,这种激进优化如果失败了,仍然会"逆优化"回退到解释执行来保证代码的正常运行.
4.4垃圾回收器( )
4.4.1什么是垃圾
说到垃圾回收器,首先需要说一下什么叫垃圾.
所有的对象都存放在堆中,而有些对象用过之后就不会再被使用了,这种就叫做垃圾.概念很容易理解,但对于JVM来说,怎么确定一个对象是否是垃圾或者说怎么找到所有的垃圾对象就需要算法的支持.
4.4.2怎么确定一个对象是垃圾