本文参考(https://github.com/jeanboydev/Android-ReadTheFuckingSourceCode/blob/master/article/java/jvm/JVM-%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6%E6%9C%BA%E5%88%B6.md)
(https://blog.csdn.net/u013630349/article/details/78342645)文章,如若侵权请通知删除。
最近面试一直会被问到关于GC的问题,之前知道这方面知识,面试答的时候也能答出来,但是总是觉得没有条例的讲解和回答总会让人觉得自己这方面东拼西凑出来的,太杂乱了,所以今天有条理的总结一下GC的来龙去脉。这次仅是总结,相信以后还会从源码层次再次进行分析。
GC概述
垃圾回收是一种自动的存储管理机制。 当一些被占用的内存不再需要时,就应该予以释放,以让出空间,这种存储资源管理,称为垃圾回收(Garbage Collection)。 垃圾回收器可以让程序员减轻许多负担,也减少程序员犯错的机会。
接下来我从**什么时候?对什么东西?做了怎么样的处理?**三个方面来进行分析。
1. 首先第一个问题就是什么时候?换句话说就是GC的触发条件
GC触发的条件有两种:
(1)程序调用System.gc时可以触发;
(2)系统自身来决定GC触发的时机。
第二个条件“系统自身来决定”我最开始看到是一脸蒙逼的,什么叫自身决定,JAVA虚拟机它就算再只能也是人写的,所以肯定会有它内部的触发条件。要了解它的触发条件,就要先了解一下JVM内存空间,请看图片
程序计数器:线程私有。是一块较小的内存,是当前线程所执行的字节码的行号指示器。是Java虚拟机规范中唯一没有规定OOM(OutOfMemoryError)的区域。
Java栈:线程私有。生命周期和线程相同。是Java方法执行的内存模型。执行每个方法都会创建一个栈帧,用于存储局部变量和操作数(对象引用)。局部变量所需要的内存空间大小在编译期间完成分配。所以栈帧的大小不会改变。存在两种异常情况:若线程请求深度大于栈的深度,抛StackOverflowError。若栈在动态扩展时无法请求足够内存,抛OOM。
Java堆:所有线程共享。虚拟机启动时创建。存放对象实力和数组。所占内存最大。分为新生代(Young区),老年代(Old区)。新生代分Eden区,S