JVM垃圾回收和内存分配策略
2016-04-19 11:42
357 查看
JVM的垃圾回收
JVM垃圾回收主要完成以下几个方面的工作:哪些内存需要回收
什么时候回收
怎么回收
问题一,有两个子问题需要回答
JVM内存布局中哪些部分进行垃圾回收?
程序计数器、虚拟机栈、本地方法栈三个区域是与线程紧密相关的,每个栈帧分配的内存大小在编译期是可知的,并且会随着线程的结束而释放相应的内存。堆区和方法区所需的内存随着程序的运行而动态变化,是垃圾回收的主要区域。
对象何时可以被回收?(对象存活判定算法)
即对象存活性判定问题。主要有两种策略来决定对象的“死与活”, 引用计数法和可达性分析法。
引用计数法:为每个对象添加一个引用计数器,当引用计数器计数到0时,对象就不可能再被使用了。这种方法很直观,但是对对象间相互循环引用的情况不能进行垃圾回收。
可达性分析法:从一系列的GCRootSet中的对象开始,根据引用关系构建引用关系链,在这些引用关系链中的对象是可达的,否则是不可达的。
GCRootSet中的对象主要包括:方法栈帧中引用的对象、类的静态成员引用的对象,方法区中常量引用的对象,本地方法栈中引用的对象。
问题二,垃圾回收的时间
JVM中存在固定的垃圾回收线程,在某些时间执行垃圾回收算法。对不可达的对象,要经过两次标记过程:
第一次,被标记并筛选,筛选准则是是否有必要执行finalize()方法。
对于判定为有必要执行finalize()方法的对象,添加到F-Queue的队列中,并稍后由Finalizer线程去执行,(不承诺等它结束)。
第二次,回收 “即将回收”集合中的对象。
问题三,垃圾收集算法
标记-清除算法
标记过程就是判定对象是否可达的过程,清除即回收对应的区域。最基础的算法,缺点:效率问题,内存碎片。
复制算法
将可用内存空间分为大小相等的两块,每次只使用其中一块。当这一块内存即将用完时,将其中的存活对象复制到另外一块中去,并一次性清空本块内存。
改进:根据%98对象都是朝生夕死,原理。新生代维持%10的空闲区(Eden + 2 Survivor),不够时由老年代分配担保。
标记-整理算法
适用于老年代中(多数对象都存活), 先标记,然后让所有对象向一端移动,清理掉端边界以外的对象。
分代收集算法
将堆分为新生代、老年代。老年代:标记整理算法,新生代:复制算法。
安全点(Safe Point): GC垃圾回收的暂停点。
垃圾收集器:实例
Serial收集器:单线程,Stop the World.SerialOld:
ParNew收集器:Serial的多线程版本。
Parallel Scavenge 收集器:以吞吐量为控制目标。
停顿时间和吞吐量的矛盾:停顿时间关系到交互效果,吞吐量关系到CPU利用效率。减小新生代空间可以减小停顿时间,但是回收频率必须变高,因此吞吐量变小了。
ParallelOld: 用于老年代,控制吞吐量。
CMS:并发收集,低停顿。
G1收集器:
分配策略:对象优先在Eden区域,大对象直接进入老年代,长期存活的对象进入老年代(年龄阈值),动态年龄判定,空间分配担保。
相关文章推荐
- Python动态类型的学习---引用的理解
- XP下使用虚拟机安装配置Solaris[多图]
- Java 6 JVM参数选项大全(中文版)
- VirtualBox虚拟机XP与宿主机Ubuntu互访共享文件夹
- Linux下三大免费桌面虚拟机评测
- 当存储无可用空间时无法启动虚拟机
- Windows 8虚拟机不能全屏的解决方法
- 用 GNOME Boxes 下载一个操作系统镜像
- 土人系列AS入门教程 -- 对象篇
- IE7降低内存和降低CPU的几个技巧
- C#托管堆对象实例包含内容分析
- 如何高效的使用内存
- DOS下内存的配置
- C#实现获取不同对象中名称相同属性的方法
- XP/win2003下发现1G的内存比512M还慢的解决方法
- javascript asp教程第十一课--Application 对象
- PowerShell中使用Out-String命令把对象转换成字符串输出的例子
- PowerShell实现动态获取当前脚本运行时消耗的内存
- VBS教程:对象-正则表达式(RegExp)对象
- C#实现把dgv里的数据完整的复制到一张内存表的方法