JVM内存回收机制简述
JVM内存回收机制涉及的知识点太多了,了解越多越迷糊,汗一个,这里仅简单做个笔记,主要参考《深入理解Java虚拟机:JVM高级特性与最佳实践(第二版)》
目前java的jdk默认虚拟机为HotSpot,因此本文涉及虚拟机相关内容都指HotSpot虚拟机
本文主要关注GC的回收:判断哪些对象可回收,如何回收,回收机制
判断哪些对象可回收
GC是通过对象是否存活来决定是否进行回收,判断对象是否存活主要有两种算法:引用计数算法、可达性分析算法
- 引用计数算法
引用计数的算法原理是给对象添加一个引用计数器,每被引用一次计数器加1,引用失效时减1,当计数器0后表示对象不在被引用,可以被回收了,引用计数法简单高效,但是存在对象之间循环引用问题,可能导致无法被GC回收,需要花很大精力去解决循环引用问题 - 可达性分析算法
可达性分析的算法原理是从对象根引用(堆栈、方法表的静态引用和常量引用区、本地方法栈)开始遍历搜索所有可到达对象,形成一个引用链,遍历的同时标记出可达对象和不可达对象,不可达对象表示没有任何引用存在,可以被GC回收
如何回收
找到可回收对象后,如何进行回收呢?
内存回收算法主要有标记-清除、停止-复制、标记-整理,不同算法使用不同的场景,总体来说停止-复制算法适合对象存活时间短,存活率低的新生代,标记-清除和标记-整理算法适合对象存活时间长,存活率高的老年代
- 标记-清除(Mark-Sweep)
通过可达性分析算法标记所有不可达对象,然后清理不可达对象。这种算法会形成大量的内存碎片 - 停止-复制(Stop-Copy)
将新生代内存按照8:1:1的比例分为一个eden区和两个survivor(survivor0,survivor1)区,回收时先将eden区存活对象复制到一个survivor0区,然后清空eden区,当这个survivor0区也存放满了时,则将eden区和survivor0区存活对象复制到另一个survivor1区,然后清空eden和这个survivor0区,此时survivor0区是空的,然后将survivor0区和survivor1区交换,即保持survivor1区为空, 如此往复,当survivor1区不足以存放 eden和survivor0的存活对象时,就将存活对象直接存放到老年代(这时我们可能回想,若是老年代也满了咋办,若是老年代也满了就会触发一次Full GC,也就是新生代、老年代都进行回收,若是内存还不够呢。。。,还不够那不废话了吗,OutOfMemory,不陌生吧哈哈)。从停止-复制算法的原理上我们可以看到,这种算法对于存活率较低的对象回收有着非常高的效率,而且不会形成内存碎片,但是会浪费一定的内存空间,适合对象存活率较低的新生代使用,如果在对象存活率较高的老年代采用这种算法,那将会是一场灾难 - 标记-整理(Mark-Compact)
通过可达性分析算法标记所有不可达对象,然后将存活对象都向一个方向移动,然后清理掉边界外的内存。这种算法是将存活对象向着一个方向聚集,然后将剩余区域清空,这种算法适合对象存活率较高的老年代
GC回收机制:分代收集算法
JVM内存收集算法基本上都是采用分代收集算法,即将内存划分为新生代、老年代,也有人把方法区算做永久代
- 新生代
对象被创建时,内存分配都是发生在新生代(大对象直接分配在老年代),绝大多数对象都是朝生夕灭,创建后很快就会不在使用,变为不可达的对象,被GC回收掉。新生代的对象存活率很低(到底有多低?研究表明有高达98%的对象创建后很快就消亡,想象一下平时编程,除了全局变量,局部变量在退出调用方法后还有几个能存活),存活时间都很短,新生代发生的GC也叫做Minor GC,MinorGC发生频率比较高(不一定等Eden区满了才触发) - 老年代
当对象在新生代发生了多次Minor GC后仍然存活的对象即进入老年代,老年代的对象比新生多很多,当然了内存比新生代也大很多(大概比例是1:2,即新生代占用堆内存总量的1/3),当老年代内存满时触发Major GC即Full GC,Full GC发生频率比较低,老年代对象存活时间比较长,存活率标记高
一般来说我们所说的GC都是发生在新生代和老年代,新生代对象存活时间短,存活率低一般采用停止-复制算法,老年代对象存活时间长,存活率高,一般采用标记-整理、标记-清楚算法,具体采用何种算法和具体采用的垃圾收集器有关
GC里面有些类似未成年人和成年人,新创建的对象为新生代,新生代想要成为老年代需要经过一定的成长(总得一点点长大是吧),新创建的对象年龄为1,每发生一次Minor GC,存活对象的年龄增加1,当经历了15次Minor GC后,仍然存活的对象达到15岁,成达到法定成年年龄15岁(默认是15),正式成为成年人(老年代),对象成年后也就没有了年龄概念,直到对象死亡,会一直呆在老年代,当然也有一些老不死的(静态变量、常量等),会与世长存,除非地球灭亡(GC崩溃)
GC收集器
GC采用分代回收算好后,起着重要作用的是GC收集器,GC收集器分为新生代收集器和老年代收集器,不同的收集器使用不同的收集算法,有着不同的特点,由于目前的收集器在内存回收时无法消除(Stop-the-world),即在回收内存时不可避免的停止用户线程,目前的收集器只能使停顿时间越来越短,但是无法彻底消除,主要的收集其中Parallel Scavenge和Parallel Old是追求吞吐量为目标,其它的收集器都是追求高响应,低停顿,
新生代收集器:Serial、PraNew、Parallel Scavenge
老年代收集器:Serial Old、Parallel Old、CMS
- Serial收集器(复制算法)
新生代单线程收集器,标记和清理都是单线程,优点是简单高效。 - Serial Old收集器(标记-整理算法)
老年代单线程收集器,Serial收集器的老年代版本。 - ParNew收集器(停止-复制算法)
新生代收集器,可以认为是Serial收集器的多线程版本,在多核CPU环境下有着比Serial更好的表现。 - Parallel Scavenge收集器(停止-复制算法)
并行收集器,追求高吞吐量,高效利用CPU。吞吐量一般为99%, 吞吐量= 用户线程时间/(用户线程时间+GC线程时间)。适合后台应用等对交互相应要求不高的场景。 - Parallel Old收集器(停止-复制算法)
Parallel Scavenge收集器的老年代版本,并行收集器,吞吐量优先 - CMS(Concurrent Mark Sweep)收集器(标记-清理算法)
高并发、低停顿,追求最短GC回收停顿时间,cpu占用比较高,响应时间快,停顿时间短,多核cpu 追求高响应时间的选择 - G1(Garbage-First)收集器(标记-整理算法、停止复制算法)
GC最新型号,高富帅,高并发、可预测停顿、分代收集,不出意外未来主流将会逐步替代CMS,g1模糊了分代概念,虽然还是分为新生代和老年代,但是新生代和老年代不再是物理隔离,而是将内存分为n个region,以region为清理单位,整体采用标记-整理算法,region内部使用停止-复制算法。
JVM内存回收机制简述的更多相关文章
- JVM内存回收机制
1. JVM内存回收机制简述 http://www.cnblogs.com/lzrabbit/p/3826738.html
- JVM内存回收机制——哪些内存需要被回收(JVM学习系列2)
上一篇文章中讨论了Java内存运行时的各个区域,其中程序计数器.虚拟机栈.本地方法栈随线程生灭,且创建时需要多少内存,基本上在译期间就决定的了,所以在内存回收时无需特殊的关注.而堆和方法区则不同,首先 ...
- Java jvm 内存回收机制
http://blog.csdn.net/yaerfeng/article/details/51291903 在Java中,它的内存管理包括两方面:内存分配(创建Java对象的时候)和内存回收,这两方 ...
- 深入理解JVM内存回收机制(不包含垃圾收集器)
目录 垃圾回收发生的区域 如何判断对象是否可以被回收 HotSpot实现 垃圾回收算法 JVM中使用的垃圾收集算法 GC的分类 总结 参考资料 垃圾回收发生的区域 堆是java创建对象的区域(Stri ...
- Java技术专题之JVM逻辑内存回收机制研究图解版
一.引言 JVM虚拟机内存回收机曾迷惑了不少人,文本从JVM实现机制的角度揭示JVM内存回收的原理和机制. 一.Java平台逻辑架构 二.JVM物理结构 通过从JVM物理结构图我们可以看到: 1.JV ...
- Java进阶3. 内存回收机制
Java进阶3. 内存回收机制 20131029 前言: 学过C++的都知道,C++中内存需要程序员自己维护.说道这里,很多开发的同学就感觉很痛苦,当他转向Java的时候,就会说你看Java多好啊,程 ...
- JVM内存管理和JVM垃圾回收机制
JVM内存管理和JVM垃圾回收机制(1) 这里向大家描述一下JVM学习笔记之JVM内存管理和JVM垃圾回收的概念,JVM内存结构由堆.栈.本地方法栈.方法区等部分组成,另外JVM分别对新生代和旧生代采 ...
- JVM内存管理、JVM垃圾回收机制、新生代、老年代以及永久代
内存模型 JVM运行时数据区由程序计数器.堆.虚拟机栈.本地方法栈.方法区部分组成,结构图如下所示. JVM内存结构由程序计数器.堆.栈.本地方法栈.方法区等部分组成,结构图如下所示: 1)程序计数器 ...
- JVM 垃圾回收机制和常见算法和 JVM 的内存结构和内存分配(面试题)
一.JVM 垃圾回收机制和常见算法 Sun 公司只定义了垃圾回收机制规则而不局限于其实现算法,因此不同厂商生产的虚拟机采用的算法也不尽相同.GC(Garbage Collector)在回收对象前首先必 ...
随机推荐
- MMS搜索功能修改
高通平台的MMS源码中提供了搜索功能,但要先选择分类(名字,号码,信息内容,彩信主题),再输入字符,根据分类进行搜索. 而在Contacts中却不需要分类,直接根据输入字符搜索任意匹配字段.相比之下, ...
- javascript高级特性
01_javascript相关内容02_函数_Arguments对象03_函数_变量的作用域04_函数_特殊函数05_闭包_作用域链&闭包06_闭包_循环中的闭包07_对象_定义普通对象08_ ...
- Android视图状态及重绘流程分析,带你一步步深入了解View(三)
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/17045157 在前面一篇文章中,我带着大家一起从源码的层面上分析了视图的绘制流程, ...
- $(function(){})、$(document).ready(function(){})....../ ready和onload的区别
1.window.onload 当一个文档完全下载到浏览器中时,会触发 window.onload 事件. 这意味着页面上的全部元素对 javascript 而言都是可以访问的,这种情况对编写功能性的 ...
- FibonacciSequence
import java.util.Scanner; public class Fibonacci { public static void main(String[] args) { int n; f ...
- Features
imhist分析灰度图阈值分界点 bwlabel分析连通区域 SIFT Scale Invariant:尺度不变性 DoG: Difference of Gaussian, calculated by ...
- js获取div相对屏幕的坐标位置
1:div相对屏幕的坐标位置 function getDivPosition(div){ var x = div.getBoundingClientRect().left; var y = div.g ...
- java 获取本地电脑的分辨率代码
1.代码: java.awt.Toolkit tk=java.awt.Toolkit.getDefaultToolkit(); java.awt.Dimension screenSize= ...
- swift 如何给tabBarItem的相关设计
//设置tabBarItem的title,以及点击和不点击状态图片 self.tabBarController.tabBarItem = UITabBarItem(title: "投资理财& ...
- CDATA为何物?
CDATA的解释 1. 术语 CDATA 指的是不应由 XML 解析器进行解析的文本数据(Unparsed Character Data),XHTML也是如此. CDATA 部分中的所有内容都会被解析 ...