垃圾回收
一个对象如果不再使用,需要手动释放,否则就会出现内存泄漏。我们称这种释放对象的过程为垃圾回收,而需要程序员编写代码进行回收的方式为手动回收。
内存泄漏指的是不再使用的对象在系统中未被回收,内存泄漏的积累可能会导致内存溢出
java中为了简化对象的释放,引入了自动的垃圾回收(garbage collection简称GC)机制。通过垃圾回收器来对不再使用的对象完成自动的回收,垃圾回收器主要负责对堆上的内存进行回收。其他语言例如c#,python,go都拥有自己的垃圾回收器
定位垃圾的两种方法
引用计数法
一个对象被引用了一次,在当前对象头上递增一次引用次数,如果这个对象的引用次数为0,代表这个对象可回收。
当对象间出现了循环引用的话,引用计数法会失效
可达性分析算法
扫描堆中的对象,看是否能够沿着GC Root对象为起点的引用链找到该对象,找不到,表示可以回收
哪些对象可以作为GC Root?
虚拟机栈(栈帧中的本地变量表)中引用的对象
方法区中类静态属性引用的对象
方法区中常量引用的对象
本地方法栈中JNI(Native方法)引用的对象
垃圾清除算法
标记清除算法
标记和清除
1.根据可达性分析算法得出的垃圾进行标记
2.对这些标记为可回收的内容进行垃圾回收
优点:清理速度较快
缺点,碎片化严重,内存不连贯
标记整理算法
和标记清除算法前面都一致,但多了一步,对象移动内存位置使得内存连续
优点:不会有内存碎片
缺点:牺牲了性能和速度
复制算法
将内存空间一分为二,每次清除和回收时都将剩下的移动到另一端。
优点:在垃圾对象多的情况下,效率较高。清理后,内存无碎片
缺点:分配的两块内存空间,在同一时刻只能使用一般,内存使用率较低
分代收集算法
在java8时,堆被分为了两份:新生代和老年代(1:2)
对于新生代,内部又被分为了三个区域:
eden区,新生的对象都分配到这里
survivor区:分着from和to
eden,from,to(8:1:1)
MinorGC,MixedGC,FullGC的区别是什么
MinorGC(youngGC)发生在新生代的垃圾回收,暂停时间短(STW)
MixedGC新生代+老年代部分区域的垃圾回收,G1收集器特有
FullGC新生代+老年代完整垃圾回收,展厅时间长(STW),应尽量避免
垃圾回收器
G1垃圾回收器机制
强引用,软引用,弱引用,虚引用的区别
强引用:只有所有GCRoots对象都不通过强引用该对象,该对象才能被垃圾回收
软引用:仅有软引用引用该对象时,在垃圾回收后,内存如果仍然不足时会再次发出垃圾回收
弱引用:仅有弱引用引用该对象时,在垃圾回收时,无论内存是否充足,都会回收弱引用对象
虚引用:必须配合引用队列使用,被引用对象回收时,会将虚引用入队,由Reference Handler线程调用虚引用相关方法释放直接内存