JVM内存管理:GC算法精解(复制算法与标记/整理算法)

本次LZ和各位分享GC最后两种算法,复制算法以及标记/整理算法。上一章在讲解标记/清除算法时已经提到过,这两种算法都是在此基础上演化而来的,究竟这两种算法优化了之前标记/清除算法的哪些问题呢?

复制算法

我们首先一起来看一下复制算法的做法,复制算法将内存划分为两个区间,在任意时间点,所有动态分配的对象都只能分配在其中一个区间(称为活动区间),而另外一个区间(称为空闲区间)则是空闲的。

当有效内存空间耗尽时,JVM将暂停程序运行,开启复制算法GC线程。接下来GC线程会将活动区间内的存活对象,全部复制到空闲区间,且严格按照内存地址依次排列,与此同时,GC线程将更新存活对象的内存引用地址指向新的内存地址。

此时,空闲区间已经与活动区间交换,而垃圾对象现在已经全部留在了原来的活动区间,也就是现在的空闲区间。事实上,在活动区间转换为空间区间的同时,垃圾对象已经被一次性全部回收。

听起来复杂吗?

其实一点也不复杂,有了上一章的基础,相信各位理解这个算法不会费太多力气。LZ给各位绘制一幅图来说明问题,如下所示。

其实这个图依然是上一章的例子,只不过此时内存被复制算法分成了两部分,下面我们看下当复制算法的GC线程处理之后,两个区域会变成什么样子,如下所示。

可以看到,1和4号对象被清除了,而2、3、5、6号对象则是规则的排列在刚才的空闲区间,也就是现在的活动区间之内。此时左半部分已经变成了空闲区间,不难想象,在下一次GC之后,左边将会再次变成活动区间。

很明显,复制算法弥补了标记/清除算法中,内存布局混乱的缺点。不过与此同时,它的缺点也是相当明显的。

1、它浪费了一半的内存,这太要命了。

2、如果对象的存活率很高,我们可以极端一点,假设是100%存活,那么我们需要将所有对象都复制一遍,并将所有引用地址重置一遍。复制这一工作所花费的时间,在对象存活率达到一定程度时,将会变的不可忽视。

所以从以上描述不难看出,复制算法要想使用,最起码对象的存活率要非常低才行,而且最重要的是,我们必须要克服50%内存的浪费。

时间: 2024-10-31 09:12:48

JVM内存管理:GC算法精解(复制算法与标记/整理算法)的相关文章

JVM内存管理:垃圾搜集器详解

引言 在上一章我们已经探讨过hotspot上垃圾搜集器的实现,一共有六种实现六种组合.本次LZ与各位一起探讨下这六种搜集器各自的威力以及组合的威力如何. 为了方便各位的观看与对比,LZ决定采用当初写设计模式时使用的方式,针对某些搜集器,分几个维度去解释这些搜集器. client模式与server模式 在介绍本章内容之前,要说一下JVM的两种模式,一种是client模式,一种是server模式.我们平时开发使用的模式默认是client模式,也可以使用命令行参数-server强制开启server模式

JVM内存管理及GC机制

一.概述 Java GC(Garbage Collection,垃圾收集,垃圾回收)机制,是Java与C++/C的主要区别之一,作为Java开发者,一般不需要专门编写内存回收和垃圾清理代码,对内存泄露和溢出的问题,也不需要像C程序员那样战战兢兢.经过这么长时间的发展,Java GC机制已经日臻完善,几乎可以自动的为我们做绝大多数的事情. 虽然java不需要开发人员显示的分配和回收内存,这对开发人员确实降低了不少编程难度,但也可能带来一些副作用: 1. 有可能不知不觉浪费了很多内存 2. JVM花

现代JVM内存管理方法的发展历程,GC的实现及相关设计概述(转)

JVM区域总体分两类,heap区和非heap区.heap区又分:Eden Space(伊甸园).Survivor Space(幸存者区).Tenured Gen(老年代-养老区). 非heap区又分:Code Cache(代码缓存区).Perm Gen(永久代).Jvm Stack(java虚拟机栈).Local Method Statck(本地方法栈). HotSpot虚拟机GC算法采用分代收集算法: 1.一个人(对象)出来(new 出来)后会在Eden Space(伊甸园)无忧无虑的生活,直

JVM内存管理:GC简介

为何要了解GC策略与原理? 原因在上一章其实已经有所触及,就是因为在平时的工作和研究当中,不可避免的会遇到内存溢出与内存泄露的问题.如果对GC策略与原理不了解的情况下碰到了前面所说的问题,很多时候会让人不知所措. 当我们了解了相关知识以后,虽然有时候依然不能很快的解决问题,但可以肯定的是,至少不会出现无计可施的情况. GC策略解决了哪些问题? 既然是要进行自动GC,那必然会有相应的策略,而这些策略解决了哪些问题呢,粗略的来说,主要有以下几点. 1.哪些对象可以被回收. 2.何时回收这些对象. 3

JVM内存管理:垃圾搜集器简介

引言 上一章我们已经探讨过GC的各个算法,那么垃圾搜集器是什么呢? 通俗的讲,使用编程语言将算法实现出来,产生的程序就是垃圾搜集器了.既然谈到了编程语言的实现,那么在讨论垃圾搜集器的时候,就已经涉及到具体的虚拟机实现了. 或许有不少做JAVA开发的猿友还不知道,我们平时使用的JDK中,默认的JVM是hotspot,换句话说,我们大部分时候使用的JVM都是hotspot的实现版本,因此,本次LZ讨论垃圾搜集器都是基于hotspot版JVM来进行的,请各位猿友要知晓这一点. 更直观的,我们可以在我们

编程-位操作 算法精解 C语言描述

问题描述 位操作 算法精解 C语言描述 bit_rot_left是怎么操作的?bits[8]={0,1,2,3,4,5,6,7}左移一位得bits[8]={0,2,4,6,8,10,12,14} 解决方案 <算法精解:C语言描述> 基本信息 原书名:Mastering Algorithms with C 作者: Kyle Loudon [作译者介绍] 译者: 肖翔 陈舸 丛书名: O'Reilly精品图书系列 出版社:机械工业出版社 ISBN:9787111394266 上架时间:2012-9

解析Linux系统中JVM内存2GB上限的详解_java

我们通常使用的JVM都是32位的(64位的JVM会损失10-20%的性能,通常不建议使用),而32位程序的寻址空间应该是4GB才对,为什么Linux上的JVM内存只能使用2GB呢? 经过和JDK研发组的人员沟通,终于弄清楚了一些相关的原因.这个问题存在于早期的一些Linux版本中,特别是内核2.5以前的版本,2.6以后的版本就基本上没有这个问题了.原来这些Linux版本对进程有个对内存2GB的限制,是一个地址连续的内存块大小的上限,而JVM的堆空间(heap size)需要连续的地址空间,因此,

JVM内存管理:GC算法精解---分代搜集算法

引言 何为终极算法? 其实就是现在的JVM采用的算法,并非真正的终极.说不定若干年以后,还会有新的终极算法,而且几乎是一定会有,因为LZ相信高人们的能力. 那么分代搜集算法是怎么处理GC的呢? 对象分类 上一章已经说过,分代搜集算法是针对对象的不同特性,而使用适合的算法,这里面并没有实际上的新算法产生.与其说分代搜集算法是第四个算法,不如说它是对前三个算法的实际应用. 首先我们来探讨一下对象的不同特性,接下来LZ和各位来一起给这些对象选择GC算法. 内存中的对象按照生命周期的长短大致可以分为三种

JVM内存管理:GC算法精解(五分钟让你彻底明白标记/清除算法)

首先,我们回想一下上一章提到的根搜索算法,它可以解决我们应该回收哪些对象的问题,但是它显然还不能承担垃圾搜集的重任,因为我们在程序(程序也就是指我们运行在JVM上的JAVA程序)运行期间如果想进行垃圾回收,就必须让GC线程与程序当中的线程互相配合,才能在不影响程序运行的前提下,顺利的将垃圾进行回收. 为了达到这个目的,标记/清除算法就应运而生了.它的做法是当堆中的有效内存空间(available memory)被耗尽的时候,就会停止整个程序(也被成为stop the world),然后进行两项工