JVM笔记(二) 垃圾收集器(1)
垃圾收集器
主要通过阅读《深入了解Java虚拟机》(周志明 著)和网络资源汇集而成,为本人学习JVM的笔记。同时,本文理论基于JDK 1.7版本,暂不考虑 1.8和1.9 的新特性,但可能初略提到。
一、GC概念
垃圾收集(GC,Garbage Collection),就是在动态分配内存后对内存进行自动回收。
- 哪些内存需要回收?
- 已死对象所占的内存需要回收 。
- 什么时候回收?
- 当内存不够用时执行垃圾回收,主要分为 Minor GC(新生代垃圾回收) 和 Major GC(又称 Full GC,老年代垃圾回收)。
- 堆(head)可以分为 Eden Space(新手村)、Survivor Space(幸存者区) 和 Tenured Gen(养老区)。对象会被优先分配到 Eden 区,大对象会直接分配到 Tenured Gen。
- 当 Eden 区满了的话发生 Minor GC,有引用的对象将被移到 Survivor 区。Survivor 区定期(可以自定义)进行GC;经历过一定次数GC仍然幸存的对象,将被送入到 Tenured Gen。当Tenured Gen 满了会发生 Major GC,或者受 HandlePromotionFailure 参数控制强制 Major GC。
- 如何回收?
新生代由于对象产生比较多并且大都是朝生夕灭,所以一般使用复制算法;而老年代的生命力很强,所以建议使用标记-助理算法。
二、判断对象是否可以回收
程序计数器、虚拟机栈和本地方法栈,对于线程而言是私有的。当线程结束时,它们会被自动回收,所以不需要过多考虑回收问题。
对于Java程序而言,需要回收内存的地方主要就是堆(大部分对象的存放位置),回收对堆内存的分配。判断方法:
1. 引用计数法
给对象添加一个引用计数器,每当有一个地方引用它时,计数器值加1;当引用失效时,计数器 值减1;如何时刻计数器值为0的对象就是不能再被使用的。但是,这种方法难以解决对象之间相互循环引用的问题(主流的Java虚拟机没有引用这种计数方法来管理内存)。
2. 可达性分析算法(根搜索算法)
通过一系列名为”GC Roots“对象作为起始点,从这些节点开始往下搜索,搜索过的路径称为引用链。当一个对象到 GC Roots 没有任何引用链相连时,则证明该对象是不可用的,会被判定为可回收对象。
GC Roots 对象
(1) 虚拟机栈(栈帧中的本地变量表)中引用的对象。
(2) 方法区中类静态属性引用的对象。
(3) 方法区中常量引用的对象。
(4) 本地方法栈中引用的对象(Native 对象)。
3. 四种引用
以上谈到的两种算法其实都与”引用”有关。
(1)强引用(Strong Reference)
在代码中普遍存在。只要强引用还存在,垃圾收集器永远不会回收被引用的对象。当内存空间不足时,Java虚拟机宁愿抛出OOM,使程序异常终止。
(2)软引用(Soft Reference)
在内存空间不足的情况下,虚拟机才会回收这种对象。软引用只要通过SoftReference 类来实现,可以作为内存敏感的高速缓存。
(3)弱引用(Weak Reference)
GC后都会回收的一类对象,可以通过WeakReference 类来实现。
(4)虚引用(Phantom Reference)
可以通过PhantomReference 类来实现,为一个对象设置虚引用的唯一目的就是能在这个对象收集器回收时收到一个系统通知。
三、生存还是死亡
一个对象死亡的经历:
- 如果对象在进行可行性分析后发现没有与 GC Roots 相连接的引用链,则将其第一次标记并进行一次筛选。
- 筛选条件:该对象有没有必要执行 finalize() 方法
- 没有必要执行的情况:
对象没有覆盖 finalize() 方法;
finalize() 方法已经被虚拟机调用过了。
- 若有必要执行 finalize() 方法,将对象放到 F-Queue 队列中。
- 虚拟机自动建立 Finalizer 线程(低优先级)去执行该方法(PS:若对象在该方法中执行缓慢甚至死循环,会导致严重后果,甚至导致内存回收系统崩溃)。
- finalize() 也是对象逃脱死亡的最后一次机会:
- GC 会对队列中对象进行第二次标记。
- 若对象与引用链上任何一个对象建立关联,即可脱离被回收的命运。
- 第二次标记后,将对象移出队列,并最终被系统回收。
任何一个对象的 finalize() 方法只会被系统调用一次!
finalize() 方法的代价高昂,不确定性大,无法保证各个对象的调用顺序。完全可以使用 try-finally 等方法来实现它的功能。但还是要了解一下Java的对于判断对象存亡的执行机制。
其他
- 当GC与非GC时间耗时超过了 GCTimeRatio 的限制时,会触发 OOM。
- GC调优:
- 用 NewRatio 来控制新生代和老年代的比例。
- 用 MaxTenuringThreshold 来控制进入老年代前的生存次数。
- 使老年代存储空间延迟达到 Major GC。
参考资料
- 《深入了解Java虚拟机》(周志明 著)
JVM笔记(二) 垃圾收集器(1)的更多相关文章
- JVM笔记(三) 垃圾收集器(2)收集算法
垃圾收集器2:收集算法 主要通过阅读<深入了解Java虚拟机>(周志明 著)和网络资源汇集而成,为本人学习JVM的笔记.同时,本文理论基于JDK 1.7版本,暂不考虑 1.8和1.9 的新 ...
- jvm系列 (二) ---垃圾收集器与内存分配策略
垃圾收集器与内存分配策略 前言:本文基于<深入java虚拟机>再加上个人的理解以及其他相关资料,对内容进行整理浓缩总结.本文中的图来自网络,感谢图的作者.如果有不正确的地方,欢迎指出. 目 ...
- 深入理解Java虚拟机之读书笔记二 垃圾收集器
1.对象已死? a.引用计数算法:缺点是它很难解决对象之间的相互循环引用的问题,Java语言中没有选用它. b.根搜索算法(GC Roots Tracing):通过一系列的名为"GC Roo ...
- JVM探秘:垃圾收集器
本系列笔记主要基于<深入理解Java虚拟机:JVM高级特性与最佳实践 第2版>,是这本书的读书笔记. 垃圾收集器 垃圾收集算法是是内存回收的方法论,垃圾收集器是内存回收的具体实现.不同的虚 ...
- 【JVM】JVM中的垃圾收集器
垃圾收集器组合 Serial+Serial Old Serial+CMS ParNew+CMS ParNew+Serial Old Paralle Scavenge + Serial Old Para ...
- JVM学习笔记——GC垃圾收集器
GC 垃圾收集器 Java 堆内存采用分代回收算法,因此 JVM 针对新生代和老年代提供了多种垃圾收集器. 1. Serial 收集器 Serial 收集器是单线程收集器,采用复制算法. 是最基本的垃 ...
- jvm七种垃圾收集器
JVM_七种垃圾收集器介绍 本文中的垃圾收集器研究背景为:HotSpot+JDK7 一.垃圾收集器概述 如上图所示,垃圾回收算法一共有7个,3个属于年轻代.三个属于年老代,G1属于横跨年轻代和年老 ...
- JVM学习记录-垃圾收集器
先回顾一下上一篇介绍的JVM中常见几种垃圾收集算法: 标记-清除算法(Mark-Sweep). 复制算法(Copying). 标记整理算法(Mark-Compact). 分代收集算法(Generati ...
- 《深入java虚拟机》读书笔记之垃圾收集器与内存分配策略
前言 该读书笔记用于记录在学习<深入理解Java虚拟机--JVM高级特性与最佳实践>一书中的一些重要知识点,对其中的部分内容进行归纳,或者是对其中不明白的地方做一些注释.主要是方便之后进行 ...
随机推荐
- max3232
max3232采用专有低压差发送器输出级,利用双电荷泵在3.0V至5.5V电源供电时能够实现真正的RS-232性能,器件仅需四个0.1uF的外部小尺寸电荷泵电容.max3232确保在120kbps数据 ...
- C++ shared_ptr的用法
一. http://www.cnblogs.com/welkinwalker/archive/2011/10/20/2218804.html 二.http://www.cnblogs.com/Tian ...
- IDEA使用技巧:CamelCasePlugin插件
CamelCasePlugin是一款可以快速进行格式转换的工具,较常用到的是大小写转换.驼峰式转换等. 1.打开idea,然后打开设置.点击Plugins 2.快捷键shift+alt+u
- 解决Floodlight界面无法显示问题
参考: 解决Floodlight1.2+Mininet问题及使用安装 解决Floodlight界面无法显示问题 执行以下命令启动Floodlight时: java -jar target/floodl ...
- css未知大小的图片居中
未知大小的图片在指定大小的div盒子中垂直水平居中: 无需要JS <style> .box { /*垂直居中*/ display: table-cell; vertical-align:m ...
- C++ 实验2:函数重载、函数模板、简单类的定义和实现
1.函数重载编程 编写重载函数add(),实现对int型,double型,Complex型数据的加法.在main()函数中定义不同类型数据,调用测试. #include <iostream> ...
- Nmap从探测到漏洞利用备忘录 – Nmap简介(一)
在侦查期间,扫描一直是信息收集的初始阶段. 什么是侦查 侦查是尽可能多收集关于目标网络的信息.从黑客的角度来看,信息收集对于一次攻击非常有用,所以为了封锁恶意的企图,渗透测试者通常尽力查找这些信息,发 ...
- 【Python】【 接口自动化测试】【一】环境搭建
1. 环境配置 我电脑Windows7 64位 + Python2.7 + Oracle客户端 10.2 + cx_Oracle 10g Oracle客户端下载(为此我还申请个Oracle账号) ...
- UTC和GMT时间辨析
一.UTC和GMT 每个地区都有自己的本地时间,在网上以及无线电通信中时间转换的问题就显得格外突出. 整个地球分为二十四时区,每个时区都有自己的本地时间.在国际无线电通信场合,为了统一起见,使用一个统 ...
- django路由转发
一.路由转发 通常,我们会在每个app里,各自创建一个urls.py路由模块,然后从根路由出发,将app所属的url请求,全部转发到相应的urls.py模块中. 例如,下面是Django网站本身的UR ...