理解JVM中GC
JVM中为什么需要GC:

如图,我们程序中每个线程都会放在JVM的方法栈中,每一个线程相当于一个栈帧,当我们线程去new一个对象时,会向JVM堆中指向一块内存对象,当我们线程方法执行完后,会弹出方法栈,对象的指向也会释放掉,因此,程序中有很多这样的对象指向,当执行完后,对象不需要了释放,这些内存地址不回收的话,占用大量内存,因此java提供了GC来回收这些内存。
如何定位这些内存是否需要回收:
引用法:
根据内存对象是否被引用来断定这个内存是否需要被回收,但是这种就内存对象之前存在互相指向,但是没被栈中所指向,这种垃圾对象就回收不了。
可达性分析法:
推重从一开始指向的对象开始,往下一直衍生指向,直到最后一个,这些都是在使用的对象,其他的话就是垃圾,需要回收,这种就避免了循环引用的垃圾对象不能清除的问题。
GC回收算法类型:
标记清除:
不需要使用的垃圾对象,通过标记的方法进行清除,这样的坏处就是会让内存变的碎片化,后面有大的内存对象存放不了。
复制清除:
把使用的内存对象收集起来复制一块新的内存放过去,旧的就全部干掉。空间换时间
标记压缩:
把有引用链的内存对象都整理放一块,其他的的垃圾对象清除掉,时间换空间
分代回收:

如图,分代回收的区域占比,其中年轻代和老年代1:3,年轻代中又分为比列:eden:s1:s1=8:1:1,新建对象在年轻代eden,然后经过一次gc,保留下来的放在s1,然后下一次新建的对象和s1一起gc,然后一起放到s2,其他的就清空,s1和s2切换,相当于复制回收,当对象gc过后十五次就可以进入老年代了,当老年代满了之后,内存发生溢出,这个时候老年代再进行full-gc。
GC演化:
java -XX:+PrintCommandLineFlags -version(可以看使用哪种类型垃圾回收器)
单线程(内存少几十兆 serial)
多线程(内存<=1G parallel->JDK8默认)
多线程(内存十几G ParNew+CMS):
cms:采用三色标记法,初始标记->并发标记(三色)->重新标记 ->并发清除,有bug,导致stw时间还是较长,通常采用G1算法
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
