1 如何判断对象的生命周期已经结束
java中引用的类型:
1)强引用:
String str = new String("abc");
一个对象被强引用引用的时候,无论何时都不会被释放
2)弱引用
SoftReference<String> softRef=new SoftReference<String>(str);
一个只被弱引用指向的对象,在一次gc启动之前不会被释放
3)软引用
WeakReference<String> abcWeakRef = new WeakReference<String>(str);
只被软引用指向的对象,发生内存不足就会被释放
4)虚引用
PhantomReference<String> phanRef = new PhantomReference<String>(str);
虚引用不起作用,随时有可能被释放
判定对象是否存活的方法有两种:
1)引用计数算法:对于一个对象,每增加一个引用计数加一,每失效一个引用计数减一,计数为0的话就可以回收了。缺点是无法解决循环引用的问题
2)根搜索算法:从某些GC root开始进行深度优先搜索遍历,如果无法遍历到,说明这些对象可以回收了。选作根的变量有:
栈中活跃的对象引用, 方法区中的常量,静态属性变量
2 四种垃圾回收算法
1)Mark-Sweep:首先对能回收的对象进行标记,然后释放掉这些对象,问题是会产生内存碎片
2)Mark-Compact:首先对能回收的对象进行标记,然后移动不被释放的内存,这样未使用的内存是连续的
3)Copying:将内存一分为二,只使用一半内存,回收时把幸存的对象复制到另一半,把当前这一半直接格式化。
Java的new Generation 使用这种方法,每次把对象分配到Eden中(80%), 回收时把幸存的对象(在Eden+Survivor1)复制到一个Survivor2,一次性释放90%内存,周而复始。
4)Generational-Collection:new Generation 使用copying, old Generation使用 Mark-Compact。
3 五个内存分配回收原则
1) 优先将对象分配到Eden:对象优先分配到Eden,如果Eden的内存不足,引发一次minorGC.
2)大对象直接进入old generation: 防止new genenration中无法完成复制。
3)长期存活的对象进入old generation:每次minorGC之后,对象年龄+1, 年龄超过15后对象移入old generation
4) 动态判定对象的年龄:超过某个年龄的对象占用survivor内存超过一半,无需等到15岁直接进入old generation
5)空间分配的担保:
4 七种垃圾收集器(与是否单线程或者多线程相关,不去陈述实现的具体机制):
1)Serial
2)ParNew
3)Parallel Scavenge
4)Serial Old
5)Parallel Old
6) CMS(Concurrent Mark Sweep)
7)G1