您的位置:首页 > 其它

JVM内存管理

2016-04-17 19:54 302 查看
一、对象的状态

1.1 可达状态:有一个以上的引用变量引用它。

1.2 可恢复状态:当无引用变量引用它时,会先进入此状态。JVM准备回收,会调用该对象的finalize方法进行资源清理,如果finalize方法重新让一个以上的引用变量引用该对象,则变成可达状态,否则进入不可达状态。

1.3 不可达状态:无引用,finalize之后依然无引用,进行此状态,JVM会真正回收对象,不是立即回收,而是等到垃圾回收运行时才回收。

二、对象的引用

2.1 强引用:通过强引用可以直接访问对象。强引用是造成内存泄漏的主要原因之一。

2.2 软引用

定义:通过SoftReference类实现,当一个对象只有软引用时,JVM可能回收它。当内存空间足够时,不回收;当不足时,回收。

使用场景:当需要大量创建某个类的对象时,而且可能重新访问这些对象时。软引用是用来描述一些有用但并不是必需的对象。很适合用来实现缓存:比如网页缓存、图片缓存等。

2.3 弱引用:通过WeakReference类实现。当垃圾回收时,直接回收弱引用的对象。当要大量使用弱引用时,一般用WeakHashMap来保存。弱引用用来描述非必需对象的。

2.4 虚引用:跟没有使用引用一样。系统无法通过虚引用访问对象。主要用于跟踪被垃圾回收的状态。一般与引用队列联合使用。

2.5 注意:如果使用后三种引用,就不能保留强引用。因为用了强引用,其它三种用了也是浪费。

三、内存泄漏

定义:存在无用的内存没有被回收回来。

举例:ArrayList底层是数组,如果remove时,一个长度为4的数组,如果将其长度变成3,则最后一个对象依然存在。应该array[3]=null;

如何避免:写代码认真点!

四、垃圾回收机制

4.1 作用:1.跟踪并监控每个对象,回收;2.内存碎片管理等。

4.2 回收算法

a.串行回收:只用一个CPU来执行垃圾回收。

b.并行回收:把整个回收区域分成多个,每个由一个CPU负责回收。不会导致应用程序暂停,但需要解决与应用程序的执行冲突,开销比Stop-the-world更高。

c.Stop-the-world:会导致应用程序暂停。

d.压缩:为减少内存碎片,压缩会把所有活对象搬迁到一起。不压缩只是回收内存,会有较多的碎片。压缩会导致回收相对慢,但分配快。不压缩导致回收快,分配慢。压缩和不压缩都两次遍历整个内存,第一次统计谁是可达的,第二次把不可达的回收掉。

f.复制:将所有活对象复制到另一块相同的内存中,故不会产生碎片。优点是一次扫描整个内存。缺点是复制数据和额外的同等大小的内存。

总结:不论哪种回收算法,都是利弊参半的。实际使用时,会看场景使用。

4.3 堆内存分代回收

分代回收的依据就是对象生存的时间长短,采用不同的回收策略。

a.Young:因为绝大多数的对象不会被长时间引用,故采用复制算法。Young代包括一个Eden区和2个等大的Survivor区。每次复制会将E区和一个S区的可达对象复制到另一个S区(其中S区中存活时间已经够长的对象不再复制到另一个S区,而是Old区)。E和S的比例默认为32. 回收频率高,开销小,称为minor collection。触发条件:当无法为一个对象分配内存时,会触发minor gc, 会导致程序暂停,但时间非常短。

b.Old:经过数次还没有回收的对象会从S区转移到Old代。Old对象之前没有回收,所以将来也不太可能被回收,故这种对象会越来越多。故执行回收频率无需太高。故每次需要更长的回收时间。故采用标记压缩算法。回收过程不会大量产生碎片。当Old代快用完时,会触发major collection,会对Young和Old代进行回收。

c.Perm:用来装载Class,方法等信息,默认64M。通常不用回收。对于需要加载很多类或动态生成很多代理类的程序,往往需要加大Perm代的内存即可。

4.4 full gc解发条件:Old代空间不足| 永久代空间不足| 统计得到Minor GC晋升的旧生代的平均大小大于旧生代的剩余空间。Full GC通常与Major GC等价(http://www.zhihu.com/question/41922036/answer/94339591)。

五、写出少占用内存的小技巧

a.尽量使用直接量,如String str = “dsfads”;

b.尽量使用SB,而不是String;

c.迟早释放无用对象,如方法里的大对象没用了,但到方法尾还有很长时间,就应该=null掉。

d.尽量少用静态变量。

e.循环中少创建对象。

f.缓存经常使用的对象。

g.尽量不要使用finalize方法。

h.考虑使用SoftReference

六、类的卸载机制

一个类何时结束生命周期,取决于代表它的Class对象何时结束生命周期。当对象都没有时,就把类给卸载掉了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息