JVM垃圾回收算法总结

整理了一下JVM垃圾回收的分代回收算法,旨在能够以后能够快速熟悉这些算法,而不用去查找大量资料(可以认为是偷懒),也是为了分纤箱一下自己的一些理解,有不足或错误之处,希望大家指正,共同进步!
1.分代回收算法
分代回收算法是标记-复制算法和标记-整理算法(标记-清楚)的集合,朱亚平是对新生代和老年代分别进行处理;
在介绍分代回收算法之前首先介绍一下标记-复制算法、标记-清除和标记-整理算法;
1)标记-复制算法:将可用内存分为两部分,只用其中的一部分,当这部分内存用完时,会将存活的对象复制到另一部分内存中,然后把该部分内存清空。这样会导致内存的极大损失,新生代采用了一些优化方法;将新生代的内存分成了一块较大的Eden空间和两块较小的Survivor空间,Eden空间和Survivor空间比例为8;1。每次垃圾回收时,Eden和其中的一块Survivor清空一次把存活的对象放进另一个Survivor里;
2)标记-整理算法:当存活率较高时,复制算法是福质量就会增大,一次对于老年代才用标记-整理算法,将存活的对象想一端移动,然后清除边界以外的所有内存。
2.分代回收算法原理
分代回收分为新生代和老年代两个区域,分别采用复制算法和标记-整理算法;
1)新生代:新生代对复制的内存空间分配进行了优化,新生代区域分为一个Eden区域和两个Survivor区域,默认空间分配为8:1:1;两个Survivor分为from Survivor和to Survivor。a)其中,在Minor GC(复制算法中采用)进行时,将Eden中所有存活的对象移到to Survivor中,from Survivor所有存活的对象会根据它们的年龄决定它们去向,当它们的年龄达到阀值(默认值15,新生代的对象在每次GC一次存活下来,年龄值加一,其分代年龄值存在对象的header中),此对象将被移到老年代;否则,存活的对象辅导to Survivor中;b)然后,Eden和from Survivor区域进行清空,此时,from Survivor和to Survivor进行角色转换,to Survivor变成了之前的from Survivor(在Eden空间存满时,进行GC,移除存活的对象),而from Survivor 变成了之前的to Survivor用来一个空的内存空间来接受Eden和 to Survivor在GC时存活下来的对象。c)当toSurvivor没有足够的空间存储GC存活下来的对象,此时,需要依赖老年代进行分配担保,将这些对象存放在老年代中。
2)老年代:老年代采用标记-整理算法,因为老年代的对象存活率比较高,进行Full GC的频率比较低,而且回收的速度也比较慢(Full GC 一般会比Minor慢10倍)。
3)满足to Survivor的对象向老年代移动的条件
a)当to Survivor 的内存空间不能存储GC所有存活的对象时,会将多余的对象存放到老年代中。
b)当新生代的对象过大时,该对象将直接存储在老年代中。
c)当to Survivor中存活的对象年龄值大于年龄阀值,也将会放进老年代中。
d)动态年龄判断,大于等于某个年龄的对象超过了Survivor中的空间的一半,大于等于该年龄的所有对象经放进老年代。

调优问题:新生代过小,会导致新生代的对象非常快地进入老年代,在老年代中非常难回收;新生代过大会导致每次GC需要复制的对象过多,影响效率。

原文地址:https://www.cnblogs.com/myworldfordata/p/9027695.html

时间: 2024-08-05 02:00:08

JVM垃圾回收算法总结的相关文章

JVM垃圾回收算法(最全)

JVM垃圾回收算法(最全) 下面是JVM虚拟机运行时的内存模型: 1.方法区 Perm(永久代.非堆) 2.虚拟机栈 3.本地方法栈 (Native方法) 4.堆 5.程序计数器 1 首先的问题是:jvm如何知道那些对象需要回收 ? 目前两种标识算法.三种回收算法.两种清除算法.三种收集器 引用计数法 每个对象上都有一个引用计数,对象每被引用一次,引用计数器就+1,对象引用被释放,引用计数器-1,直到对象的引用计数为0,对象就标识可以回收 这个可以用数据算法中的图形表示,对象A-对象B-对象C

JVM垃圾回收算法 总结及汇总

先看一眼JVM虚拟机运行时的内存模型: 1.方法区 Perm(永久代.非堆) 2.虚拟机栈 3.本地方法栈 (Native方法) 4.堆 5.程序计数器 1 首先的问题是:jvm如何知道那些对象需要回收 ? 目前两种标识算法.三种回收算法.两种清除算法.三种收集器 引用计数法 每个对象上都有一个引用计数,对象每被引用一次,引用计数器就+1,对象引用被释放,引用计数器-1,直到对象的引用计数为0,对象就标识可以回收 这个可以用数据算法中的图形表示,对象A-对象B-对象C 都有引用,所以不会被回收,

JVM 垃圾回收算法

在说垃圾回收算法之前,先谈谈JVM怎样确定哪些对象是"垃圾". 1.引用计数器算法: 引用计数器算法是给每个对象设置一个计数器,当有地方引用这个对象的时候,计数器+1,当引用失效的时候,计数器-1,当计数器为0的时候,JVM就认为对象不再被使用,是"垃圾"了. 引用计数器实现简单,效率高:但是不能解决循环引用问问题(A对象引用B对象,B对象又引用A对象,但是A,B对象已不被任何其他对象引用),同时每次计数器的增加和减少都带来了很多额外的开销,所以在JDK1.1之后,

记录JVM垃圾回收算法

垃圾回收算法可以分为三类,都基于标记-清除(复制)算法: Serial算法(单线程) 并行算法 并发算法 JVM会根据机器的硬件配置对每个内存代选择适合的回收算法,比如,如果机器多于1个核,会对年轻代选择并行算法. 稍微解释下的是,并行算法是用多线程进行垃圾回收,回收期间会暂停程序的执行,而并发算法,也是多线程回收,但期间不停止应用执行.所以,并发算法适用于交互性高的一些程序.经过观察,并发算法会减少年轻代的大小,其实就是使用了一个大的年老代,这反过来跟并行算法相比吞吐量相对较低. 还有一个问题

JVM垃圾回收算法和垃圾收集器笔记

概述 程序计数器,本地方法栈,虚拟机栈随线程而生,随线程而灭. Java堆和方法区则不一样,这部分内存分配和回收的都是动态的,垃圾收集器所关注的是这部分内存. 判断对象是否是垃圾的算法 JVM没有选用引用计数算法来管理内存,最主要的是引用计数很难解决对象之间相互循环引用的问题.JVM采用了可达性分析算法来判断对象是否能回收.用GC Roots对象作为起点,向下搜索,搜索走过的路劲称为引用链(reference chain),当对一个对象到GC Roots没有任何引用链时,则证明对象不可用的. 判

JVM系列(四) - JVM垃圾回收算法

前言 前面介绍了Java内存运行时区域,其中 程序计数器.虚拟机栈.本地方法栈 三个区域随线程而生,随线程而灭:栈中的栈帧随着方法的进入和退出而有条不紊地执行着出栈和入栈操作.每一个栈帧中分配多少内存基本上是在类结构确定下来时就已知的,因此这几个区域的内存分配和回收都具备确定性.在这几个区域内不需要过多考虑回收的问题,因为方法结束或线程结束时,内存自然就跟随着回收了. Java堆 和 方法区 则不一样,一个接口中的多个实现类需要的内存可能不一样,一个方法中的多个分支需要的内存也可能不一样.我们只

JVM垃圾回收算法及分代垃圾收集器

一.垃圾收集器的分类 1.次收集器 Scavenge GC,指发生在新生代的GC,因为新生代的Java对象大多都是朝生夕死,所以Scavenge GC非常频繁,一般回收速度也比较快.当Eden空间不足以为对象分配内存时,会触发Scavenge GC. 一般情况下,当新对象生成,并且在Eden申请空间失败时,就会触发Scavenge GC,对Eden区域进行GC,清除非存活对象,并且把尚且存活的对象移动到Survivor区.然后整理Survivor的两个区.这种方式的GC是对年轻代的Eden区进行

jvm垃圾回收算法整理

java推荐 内存的自动化整理 也就是自动化解决给对象分配内存以及回收对象的内存  ,这两个问题也是主要针对java的内存模型 堆 :有效解决内存丢失等问题: 1.内存分类: 新生代: eden内存 新建的对象存储的位置 survivor0 当eden内存空间存满之后就会将存活的对象进行复制进入survivor0空间,eden内存空间进行一次GC回收 survivor1 当Eden内存和survivor0都存满之后,就会将存活的对象复制进入survivor1空间,eden和survivor0都回

JVM垃圾回收算法

1.堆的分代和区域 (年轻代)Young Generation(eden.s0.s1  space)    Minor GC (老年代)Old Generation (Tenured space)     Major GC|| Full GC (永久代)Permanent Generation (Permanent  space)[方法区(method area)]    Major GC 本地化的String从JDK 7开始就被移除了永久代(Permanent Generation ) JDK