注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

qus的博客

 
 
 

日志

 
 

《深入理解JAVA虚拟机》-垃圾收集器和内存分配策略  

2013-02-11 23:21:59|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
GC收集器确定的3个问题:
哪些对象需要回收
什么时候回收
怎么回收

1.对象回收算法(哪些对象需要回收
引用计数法:每个对象有一个计数器,为0的时候回收。难以解决对象相互引用。
根搜索算法:从GC ROOTS开始向下搜索确定对象可到达与不可到达。(有向图的搜索算法)
GC ROOTS的对象包括
虚拟机栈中引用的对象
类静态属性引用对象
常量引用对象
本地方法中的JNI的引用对象

2.引用分类:
强引用:不能进行回收的对象
弱应用:在内存不足的时候会回收的对象
软引用:无论内存是否足够,都会回收的对象
虚引用:不影响对象回收的逻辑。为一个对象这只虚引用的目的是,对象被回收的时候收到系统通知。

(finalize细节:
如果一个对象不可到达,将会进入F-Queue的队列之中。
如果对象覆盖了finalize方法且没有执行过,将会调用finalize方法

2.垃圾收集算法(怎么回收)
标记-清除算法
最基本的回收算法,标记所有的回收对象然后清除。
缺点:
一是效率(效率低的原因估计是回收对象会比不回收对象多很多,对所有的要回收的对象进行清理赋0会耗费很长的时间)
二是空间变得不连续

标记-复制算法
将内存分为2个对等区域,A区域回收的时候,将不回收的对象顺序复制到B区域
缺点:少了一半的总内存

标记-整理算法
标记所有对象,然后每个对象顺序复制到内存的逻辑地址的低位

分代收集算法
基本上,现在使用的算法是基于标记复制和标记整理的新老年代的分代收集算法。
首先内存区分为新生代和年老代。
新生代的核心收集算法是经过改进的标记复制算法
内存区分为2个大小为10%的eden和90%的survivor
程序运行的时候使用1个eden和survivor,当进行回收的时候复制对象到另一个eden
如果,另一个eden不够内存空间(即有多于1/9的内存对象不能被回收)需要年老代进行担保,临时租借内存给eden使用。

年老代是针对对象存活率非常高的对象的区域,由于没有区域给它做内存担保,所以使用标记整理,或者标记清除算法。

新生代的对象经过15次垃圾回收后进入年老代。(针对具体的不同收集器不同的做法)

3.垃圾收集器(怎么回收与何时回收的具体实现)

stw代表stop the world 用户线程被暂停
   
  新生代收集器 Serial  PerNew  ParrallelScacvenge
 年老代收集器 特点和细节 单线程收集器
收集的时候会暂停其它用户线程
简单,高效,cilent端使用
 serial的多线程版本
一样会stw
 可控制吞吐量的收集器
有参数MaxGCPauseMillis和GCTimeTatio
还有UseAdaptiveSizeProlicy可开新生代的参数自调
  CMS  标记清除算法
4个步骤
1.初始标记(stw),仅标记GCROOTS能直接关联的对象,速度快
2.并发标记,GCROOTS tracing过程,和用户线程并发尽行
3.修正并发标记阶段,因用户线程导致对象的标记产生变变动的那一部分对象的标示记录,不处理新增加要回收的垃圾(stw)
由于大部分对象已经完成标记,所以速度比较快
4.并发清理

优点:并发,低停顿
缺点:1.占据了CPU的资源,用户线程的可用资源减少
2.有浮动垃圾,而需要预留内存给用户线程使用。默认在68%的时候进行垃圾回收。如果,预留内存无法满足程序需要,会出现“concurrent mode failure”,临时使用Serial Old进行垃圾回收
3.内存空间连续,大对象找不到空间分配的时候,提前触发一次full GC老年代回收。可使用参数UseCMSCompactAtFullCollection在fullgc的时候进行一次内存顺序整理


 可配合 可配合 
 Serial-Old单线程,使用标记整理,
JDK1.5前和ParallelScavenge搭配使用
,现作为CMS的后备预案 
 可配合 可配合 可配合
 Parallel-Old ParrallelScacvenge的老年代版本,使用标记整理   可配合
   
一些内存分配的原则:
基于Serial/Serial-Old收集器
1.对象优先在eden分配
2.大对象直接进入老年代,好处,可以避免大对象在新生代中多次复制。
(java内存分配遇到大对象,是坏消息
更坏的消息是,遇到一群“朝生夕灭”的大对象)
3.长期存活的对象进入年老代,默认大于15岁(即15次回收都没有回收这个对象)
4.动态对象年龄判定,如果同年龄的对象的大小大于survivor的一半,所有大于或等于给年龄的对象进入老年代
5.空间分配担保
1.在minor gc之前时候
判断晋升老年代的对象的平均是否大于老年代可用空间,大于到2,小于到3
2.进行full gc,结束
3.判断是否有老年代担保,有到4,没有到5
4.进行minor gc,如果实际情况老年代的担保空间不足,出发full gc
5.进行full gc
这些复制流程的目的还是为了减少full gc的次数

附录
垃圾收集器常用参数 P65
  评论这张
 
阅读(131)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017