实战java虚拟机(二)——垃圾回收算法

前言



垃圾回收是Java体系最重要的组成部分之一,和C/C++不同,Java虚拟机提供了全自动的内存管理方案,尽量减少了我们在内存资源管理方面的工作量,但是这套方案也并不完美,因此我们也需要深入学习垃圾回收的算法,在工作中遇到内存溢出等问题时也容易更快找到问题所在

一、引用计数法



引用计数法是最古老的垃圾收集算法,它的实现非常简单,只需要为每个对象配备一个整型计数器即可,当对象被引用时,计数器+1,引用失效时计数器-1.

显而易见,这种方式有着两个非常严重的问题:

1.无法处理循环引用,如果对象A,B相互引用,且不存在第三个对象引用了A或B,按道理AB两个对象是垃圾对象需要被回收,但是AB之间的相互引用导致计数器永远不为0,无法被回收

2.在每次引用产生和消除的时候,需要额外的操作对计数器做加减法,对性能会存在一定影响

因此,Java虚拟机没有选择此算法作为回收算法

二、标记清除法



标记清除法是现代垃圾回收算法的思想基础,它分为两个阶段:标记阶段和清除阶段。一种简单的具体实现方法如下

在标记阶段,通过根节点标记所有从根节点开始的可达对象,在清除阶段,清除所有未被标记的对象。

显然,这种方式很容易产生空间碎片,回收后的空间不连续,后续空间分配时,尤其是大对象的分配,会导致效率大大降低,这也是这种算法的最大缺点。

三、复制算法



该算法的核心思想是:将原有的内存空间分为两块,每次只使用其中一块,进行垃圾回收时,将正在使用的内存中的存活对象复制到未使用的内存块中,再清楚正在使用的内存块中的对象,完成垃圾回收。如果系统中的垃圾对象较多,算法需要复制的存活对象数量就较少,因此,在真正需要垃圾回收的时候,复制算法的效率是很高的,而且对象是统一复制到新的内存空间,确保回收后的内存空间是没有碎片的,但是这么做的代价也是很高的,系统的内存使用率将最高只有50%

四、标记压缩法



标记压缩法是一种老年代的回收算法,它在标记清除法上做了一些优化。与标记清除法相同,它有标记和清除阶段,不同的是,它不是简单的标记存活对象,而是将存活对象压缩到内存的一端,然后清理边界外的所有空间,这种方式既可以避免了碎片的产生,对内存的利用率也较高。

五、分代算法



分代算法基于生命区间长短划分成两个部分,根据每块内存区间的特点使用不同的算法,提高垃圾回收的效率。一般在新生代的是复制算法,老年代中是标记压缩/标记清除法。

六、分区算法



分区算法是将整个堆空间划分成连续不同的小空间,每个小区间独立使用回收

原文地址:https://www.cnblogs.com/gtblog/p/11460532.html

时间: 2024-07-29 05:42:03

实战java虚拟机(二)——垃圾回收算法的相关文章

java虚拟机之垃圾回收算法

标记-清除算法: 这是最基础的,就是之前所讲的两次标记,首先标记出所有 需要回收的对象,然后进行统一清除, 这有两缺点:一是效率低,标记和清除(开启低优先级进行回收)都是低效率的.第二是空间问题,标记清除会产生大量的内存碎片. 复制算法: 可以将内存分为大小相等的两块,每次只使用一块,当一快内存使用完之后,将存活的对象移到另一块, 然后将使用过的一块用垃圾回收器将其回收掉. 这种方式运行简单,效率高.缺点是缩小了内存的实际使用大小. 比如使用20M的内存,每次都只能使用10M. 并且在对象存活

Java虚拟机之垃圾回收详解一

Java虚拟机之垃圾回收详解一 Java技术和JVM(Java虚拟机) 一.Java技术概述: Java是一门编程语言,是一种计算平台,是SUN公司于1995年首次发布.它是Java程序的技术基础,这些程序包括:实用程序.游戏.商业应用程序.在全世界范围内,Java运行在超过数十亿台个人计算机上,数十亿台设备上,还包括手机和电视设备.Java由一系列的关键组件作为一个整体构建出了Java平台. Java Runtime Edition 当你下载Java,你就得到了Java运行环境(JRE).JR

【深入理解Java虚拟机】垃圾回收机制

本文内容来源于<深入理解Java虚拟机>一书,非常推荐大家去看一下这本书. 本系列其他文章: [深入理解Java虚拟机]Java内存区域模型.对象创建过程.常见OOM 1.垃圾回收要解决的问题 垃圾收集(Garbage Collection,GC),要设计一个GC,需要考虑解决下面三件事情: (1)哪些内存需要回收? (2)什么时候回收? (3)如何回收? 哪些内存需要回收? 根据<Java内存区域模型.对象创建过程.常见OOM>中介绍的java内存模型,其中,程序计数器.虚拟机栈

Java虚拟机之垃圾回收

简述 Java与那些较传统的语言比如C++有个很大不同就是垃圾回收策略了.前者通常是虚拟机自动帮我们做了,而后者就需要我们手动来完成. Java虚拟机帮我们完成了垃圾回收,是不是意味着我们就不用完全去管它了呢?当然不是的.在很多场景下,虚拟机默认做的并不能使我们满意.比如某个java应用较大时,频繁产生GC,就会非常影响我们应用的响应速度.这时候就需要我们根据自身需要,进行相应的调整.那么如何调整呢?这就需要我们对虚拟机的垃圾回收机制有所了解了. 找到将要回收的对象 如何找到要回收的对象呢?这里

Java中的垃圾回收算法

1)垃圾回收的两个关键要素: 发现无用对象. 回收无用对象的内存空间. 2)6种垃圾回收算法 引用计数法,tracing 算法,compacting算法,copying 算法,generation算法,adaptive算法. 3)detail: 引用计数法(Reference Counting Collector)引用计数法是唯一没有使用根集的垃圾回收的法,该算法使用引用计数器来区分存活对象和不使用的对象.一般来说,堆中的每个对象对应一个引用计数器.当每一次创建一个对象并赋给一个变量时,引用计数

JVM调优(二)垃圾回收算法

原文出处: pengjiaheng 可以从不同的的角度去划分垃圾回收算法: 按照基本回收策略分 引用计数(Reference Counting): 比较古老的回收算法.原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数.垃圾回收时,只用收集计数为0的对象.此算法最致命的是无法处理循环引用的问题. 标记-清除(Mark-Sweep): 此算法执行分两阶段.第一阶段从引用根节点开始标记所有被引用的对象,第二阶段遍历整个堆,把未标记的对象清除.此算法需要暂停整个应用,同时,会产生内存碎

JAVA虚拟机:垃圾回收策略及算法

java虚拟机中的程序计数器区.虚拟机栈区.本地方法栈区3个区域是随着线程的创建而创建,随着线程的结束而结束时,内存自然得到回收,所以这三个区域不需要过多考虑内存的回收问题. java虚拟机中的方法区和虚拟机堆区2个区是所有线程共享的区域,不同的接口或类需要的内存不同,且方法区和堆区往往是在程序运行期间进行内存动态分配或回收.GC回收器的使用范围就是对这两个区域的定义. 虚拟机堆区垃圾回收策略:GC回收器在回收内存之前,首先要知道哪些对象可以回收,即“死去”的对象是可以回收的:哪些对象不能回收,

java虚拟机的垃圾回收机制原理

1.常用的算法: a.引用计数法:为每一个对象配置一个整形计数器,当有一个引用时,计数器+1,引用失效时,计数器-1.计数器为0,进行垃圾回收 存在的问题:A对象引用B,B对象引用A.循环引用,无法清除,引起内存泄漏 java的垃圾回收器没有使用该算法 b.标记-清除算法 分标记阶段和清除阶段. 存在问题:释放后的空间不是连续的.内存分配不连续的空间,工作效率较低 c.复制算法 将内存空间分为两块,每次只使用其中一块,垃圾回收时,将正在使用的内存中存活的对象复制到未使用的内存中,然后,清除使用的

《深入理解JAVA虚拟机》垃圾回收时为什么会停顿

停顿现象 很多网上资料都会说到JAVA语言的一个劣势就是垃圾搜集时,整个进程会停顿. 到底是不是呢? 答案是确实存在. 为什么会停顿 垃圾收集的一个前提是要判断进程中的对象哪些是垃圾内存,哪些不是. 怎么判断呢,JVM里面使用了一种叫可达性分析的技术来枚举根节点. 一言以蔽之,JVM的内存空间里的若干对象都会有联系,形成树结构,如果一个对象通过寻路,能够找到根节点,那么这个对象就是活的,不能回收,否则就要回收. 在这个可达性分析过程中,是必须要求分析过程中树结构是不变的,也就是一致的.这意味着这