这篇博客是对 http://www.cnblogs.com/sunniest/p/4575144.html 学习和整理。
垃圾回收算法要做的两件事:1.定位无用对象 2.回收对象占用空间
对于定位无用对象,有两种算法:引用计数算法,根搜索算法。
引用算法通过统计这个引用的使用情况来决定这个对象引用要不要回收,注意下他的优缺点。
根搜索通过将所有的引用关系生成图来产生无关节点的方式来找到回收节点(值得注意的是只有以GC root为根的图才是有效的,我的理解是森林中只有一棵树有效,其他树都是无用节点),注意下可以作为root的对象(方法区中的静态属性,常量,本地变量表和native对象)。
对于回收,有以下方法:清除,整理,copying以及比较复杂的generation算法
清除算法直接清除无用对象,会产生内存碎片,
整理算法在句柄和句柄表的支持下对清除以后的内存进行整理,但是由于使用了句柄和句柄表处理时间会较长
copying算法并不直接寻找无用对象,而是寻找活动对象,将活动对象复制到另一个区中,再直接清空当前的对象区。
generation算法需要另外拿出来讲。
generation算法:分代算法
generation基于这样一个事实:不同的对象的生命周期是不一样的,将对象分成三代,新生代Young,年老代Tenured和持久代Perm
持久代用于存放静态文件,如Java类、方法等,其余的对象都是先装入新生代,满足一定条件(新生代的存活区呗装满)以后才会装入年老代。
在分代算法中,GC集中在新生代,称为Scavenge GC,但只有Full GC才能处理年老代和持久代,所以full gc的触发条件中就有持久代被装满和年老代被装满,还有system.gc(),上一次GC之后Heap的各域分配策略动态变化(这个表示不是很懂)。
在新生代和年老代的不同的收集器算法中:serial和Par以及CMS三种
GC不是万能的,需要开发者自己处理的部分
1.静态集合类像HashMap、Vector等的使用最容易出现内存泄露
2.各种连接,数据库连接,网络连接,IO连接等没有显示调用close关闭,不被GC回收导致内存泄露。
3.监听器的使用,在释放对象的同时没有相应删除监听器的时候也可能导致内存泄露。
网友评论