Java核心篇之JVM--day3
Java JVM详解--通俗易懂教程
JVM:Java虚拟机的简称。
谈到JVM,通常会聊到三个问题:
1. 什么时候触发Java GC?
2. 对什么东西进行Java GC?
3. 如何进行Java GC?
首先解决第一个问题:
1. 什么时候触发Java GC?
GC分为minor GC和Full GC。
Full GC:
2. 对什么东西进行GC ?对GC root搜索不到,并且经过第一次标记,清除之后,仍然没有复活的对象进行GC。
3. 做了什么工作,怎么进行GC?
主要做了清理对象,整理内存的工作,Java堆中主要是有新生代和年老代,他们采用不同的回收方式,例如新生代采用了标记复制的算法(因为其生存时间比较短),新生代进行gc的时候,会把eden区存活的对象放到另外一个survival区域里面,然后把eden区和另外一个survival区清除。而年老代采用了标记清除的算法,首先标记出存活的对象,然后移到另一端,这样也能减少内存碎片化。
标记清除算法:标记出需要回收的对象,标记完成后,统一回收所有被标记的对象。(两个不足:效率不高:标记和清除都不高;空间问题:产生大量不连续的内存碎片,可能导致以后在分配较大对象的时候因无法找到连续的内存而触发GC)
复制算法:(新生代)比较适合对象存活率比较低的场景。应用于新生代,它主要是把内存分成两个块,每次只使用一块,就像新生代一样,有两个区域:一个是eden区,一个是survival区。这样也就解决了内存碎片化的问题。
标记整理算法:(老年代)比较适合对象存活率比较高的场景,应用于老年代,将所有存活对象都移向另一端,然后直接清除掉端边界外的内存。
引用计数法:每个对象都有一个引用计数器,当对象被引用一次的时候,计数器+1,当对象引用失效的时候,计数值-1,实时性,当对象的引用计数器的值为0,则立刻回收,不能解决循环引用的问题。
可达性算法分析:从GC Root作为起点开始搜索,,那么整个连通图的对象都是存活的对象,对于GC Root无法到达的对象便成了垃圾回收的对象。(解决循环引用的问题)
强引用>软引用>弱引用>虚引用
强引用:GC永远都不会回收的对象。内存空间不足时,宁愿抛出OutOfMemoryError。
软引用:内存空间不足时会考虑回收它,空间足够的时候不会
弱引用:不管内存空间够不够,都会回收它。
虚引用:不会影响生存时间,目的是能在这个对象被收集器回收时收到一个系统通知。
虚拟机栈中的对象
方法区的静态变量
方法区常量池的对象
在执行机制上JVM主要提供了串行GC(serial GC),并行GC(ParNew),并行回收GC(parallel scavenge)
Serial GC:在整个GC的过程中采用单线程的方式来进行垃圾回收,在回收过程中,必须停止其他所有的工作线程。 适用于单CPU,是client模式下默认的GC方式。
parNew :其实就是serialGC的多线程版本,除了使用多条线程来进行垃圾收集之外,其他行为跟serialGC差不多。,是server模式下默认使用的GC方式。能够与CMS收集器配合工作。
Parallel scavenge:它跟parNew差不多,也是一个并行的多线程收集器。不过他的关注点跟其他收集器不一样。Cms等收集器的关注点是尽可能的缩短垃圾收集是用户线程的停顿时间,而parallel scavenge的目的是为了达到一个可控制的吞吐量。(也就是CPU用于运行用户代码的时间与CPU总的消耗时间的比值)还有一个就是parallel scavenge有GC的自适应调节策略:我们可以通过一个参数,这个参数叫做userAdaptiveSizePolicy来让虚拟机帮我们动态的调整这些参数以提供最合适的停顿时间或者最大的吞吐量。
串行GC(serial old):他是serial的老年代版本,也是一个单线程收集器,使用标记整理算法。
并行GC(parallel old):是parallel scavenge 的老年代版本。使用多线程和“标记-整理”算法。
并发GC(CMS):获取最短回收停顿时间为目标的收集器。
优点是:并发收集,低停顿
总结如下:
缺点有三:
(cpu数量+3)/4,当cpu<4的时候,占用了不少于25%的cpu资源。(增量式并发收集器:让他们交替执行)
G1:G1收集器是当今收集器技术发展最前沿的成果,他是一款面向服务端应用的收集器。
过程如下:
优势:
userSerialGC:虚拟机运行在client模式下的默认值,打开此开关之后,使用serial+serial old组合收集器。
userParNewGC:打开此开关之后,使用parNew+serial Old组合收集器。
userConcMarkSweepGC:打开此开关之后,使用parNew+CMS+serial Old组合垃圾收集器,serial old作为后备收集器使用。(concurrent mode failure)
userParallelGC:server模式下的默认值,parallel Scavenge+serial old组合垃圾收集
userParallelOldGC:parallel scavenge+parallel old收集器组合收集。
SurvivalRadio:eden:survival= 8
userAdaptiveSizePolicy:GC自适应调节策略,调整Java堆各区域的大小以及进入老年代的年龄。
handlePromotionFailure:是否允许分配担保失败
ParallelGCThreads:设置并行GC时进行内存回收的线程数。