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对象何时结束生命周期。当对象都没有时,就把类给卸载掉了。
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对象何时结束生命周期。当对象都没有时,就把类给卸载掉了。
相关文章推荐
- Java 6 JVM参数选项大全(中文版)
- 书评:《算法之美( Algorithms to Live By )》
- 如何在 Ubuntu Linux 中使用 RAR 文件
- 动易2006序列号破解算法公布
- IE7降低内存和降低CPU的几个技巧
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- 如何高效的使用内存
- DOS下内存的配置
- XP/win2003下发现1G的内存比512M还慢的解决方法
- 超大数据量存储常用数据库分表分库算法总结
- PowerShell实现动态获取当前脚本运行时消耗的内存
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- C#使用DeflateStream解压缩数据文件的方法
- C# 利用ICSharpCode.SharpZipLib实现在线压缩和解压缩
- 算法练习之从String.indexOf的模拟实现开始
- C#实现把dgv里的数据完整的复制到一张内存表的方法
- C#算法之关于大牛生小牛的问题
- SQL语句实现查询SQL Server内存使用状况