关于JVM的垃圾收集(二)

自适应收集器

在第一篇:关于JVM 的垃圾收集(一)中谈到过几种垃圾收集的算法,然而我们的 JVM 启动之后并不要求彻头彻尾的死板的使用一种垃圾收集算法,固定的算法参数。因为某种情况下某些垃圾收集算法工作得更好,而别外一些收集算法在另外的情况下工作得更好,所以自适应的垃圾收集技术应运而生。自适应算法监视堆中的情形,并且对应的调整为合适的垃圾收集技术。或能是换一种垃圾收集算法,或者是调整当前算法参数,或者把堆划分为子堆,同时在不同的子堆中使用不同的算法。

简述火车算法

垃圾收集一般都会停止整个程序的运行来查找和收集垃圾对象,它们可能在程序执行的任意时刻暂停,并且暂停的时间也无法确定。垃圾收集也可能使得程序对事件响应迟钝,无法满足实时系统的要求。如果一种垃圾收集算法可能导致用户可察觉的到的停顿或者使得程序无法适合实时系统的要求,这种算法被称作破坏性。垃圾收集算法的还有一个基本目标是使本质上的破坏性尽可能少,如果可能的话,尽可能消除这种破坏性。

达到(或试图达到) 非破坏性垃圾收集的方法是使用渐进式收集算法。渐进式收集器就是不试图一次性发现并回收所有不可触及的对象,而是每次发现并回收一部分。因为每次只有堆的一部分执行垃圾收集,因此理论上说每次收集会持续更短的时间。保证这个最短时间接近某一个时长,就可以让 Java 虚拟机适合实时环境,也就可以消除用户可察觉的垃圾收集停顿,这可称之为限时渐近时垃圾收集。

渐进式收集器通常是分代收集的,大部分调用中,都是收集堆的一部分。大部分对象都是短命的,利用这一点,分代收集器在年幼子堆中比在年长子堆中更活跃。因为除了最高寿的子堆(成熟对象空间) 外,每个子堆中都可以给定一个最大尺寸,分代收集器大体上可以保证在一个最大时间内渐进地收集所有对象(最高寿的除外)。成熟对象空间无法给定最大尺寸,因为其中的对象不适合时没个去处。

于是针对成熟对象空间提供限定时间的渐时收集,Richard Hudson 和 Eliot Moss 提出了火车算法,目前正用于 Sun 公司的 Hotspot 虚拟机中。该算法详细说明了分代收集的垃圾收集器的成熟对象空间的组织。大体有些车厢、火车、火车站的概念,对于该算法的此处不作进一步说明了。

finalize() 方法

一个 Java 对象可以拥用终结方法:这个方法在垃圾收集器释放对象之前必须运行。但这么一个终结方法的引入并不明智,会使得 JVM 的垃圾收集的工作变得更得杂,所以别用它。

因为,存在终结方法时,垃圾收集器必须在每次在收集时执行一些额外的步骤。首先第一遍扫描时,垃圾收集器检测出不再被引用的对象,然后看那些对象上是否声明了终结方法,有则执行。当执行了所有的终结方法后,垃圾收集器必须再次从根节点或是需要执行终结的对象开始检测不再被引用的对象,这称作第二遍扫描。这个步骤是必要的,因为终结方法可能“复活”了第一遍扫描标记的对象。最后,垃圾收集器才能释放那些在第一遍和第二遍扫描中发现的都没有被引用的对象。

如果第一遍扫描标记不再引用的对象的终结方法运行过了,而后这个对象被自己或其他对象的终结方法复活了,稍后再次被收集时,执行过的终结方法就不能再执行了。同时终结方法何时被执行也是无法预测的。

时间: 2024-11-27 07:48:20

关于JVM的垃圾收集(二)的相关文章

[jjzhu学java]之深入理解JVM之垃圾收集器与内存分配策略

深入理解JVM之垃圾收集器与内存分配策略 如何判断对象已经消亡 引用计数算法 根搜索算法 引用 深入理解JVM之垃圾收集器与内存分配策略 java中对象的创建需要的内存都是在java堆中申请的,所以垃圾收集的区域就是对java堆和方法区的内存区域进行GC. 如何判断对象已经消亡 垃圾收集器的主要任务就是找出已经"消亡"的对象,将其标记并清除其说用内存的过程,如何判断某个对象已经"消亡",不同的虚拟机有不同的判断策略 引用计数算法 引用计数(Reference Cou

关于JVM的垃圾收集(一)

Java 中使用 new.newarray.anewarray 和 multianewarray 指令来创建的对象,当这些对象不再使用时由垃圾收集来释放.那么 反序列化等都是间接使用了前面的某个指令, clone() 是个本地方法? JVM 规范不需要任何特定的垃圾收集技术,甚至也没要求有垃圾收集机制.大概只是说不需要手工释放内存,具体怎么实现各 JVM 自行决定. GC 除了释放不再被引用的对象,还要处理堆碎片,整理出连续的空闲空间才能放得下新的对象.不至于出现总的空闲空间足够,但碎片太多而报

关于JVM的垃圾收集(三)

对象可触及时的生命周期 在 JVM 1.2 之前,堆中的对象分为三种状态,分别是: 1.可触及的 -- 从根节点开始可追踪到 2.可复活的 -- 从根节点开始追踪不到,但有可能被终结方法触及并复活.不仅仅是那些声明了 finalize() 方法的对象,而是所有的对象都要经过可复活状态 3.不可触及的 -- 以上两种可能性都不存在,可以真正回收它们所占据的内存了 版本 1.2 中,可触及按强弱进一步细分为: 1.强可触及 -- 即原来的可触及,从根节点开始的任何直接引用,如一个局部变量或任何从强可

JVM性能优化(三):垃圾收集

原文地址,译文地址,译者:Greenster Java平台的垃圾收集机制显著提高了开发者的效率,但是一个实现糟糕的垃圾收集器可能过多地消耗应用程序的资源.在Java虚拟机性能优化系列的第三部分,Eva Andreasson向Java初学者介绍了Java平台的内存模型和垃圾收集机制.她解释了为什么碎片化(而不是垃圾收集)是Java应用程序性能的主要问题所在,以及为什么分代垃圾收集和压缩是目前处理Java应用程序碎片化的主要办法(但不是最有新意的). 垃圾收集(GC)的目的是释放那些不再被任何活动对

海子-JVM的内存区域划分

学过C语言的朋友都知道C编译器在划分内存区域的时候经常将管理的区域划分为数据段和代码段,数据段包括堆.栈以及静态数据区.那么在Java语言当中,内存又是如何划分的呢? 由于Java程序是交由JVM执行的,所以我们在谈Java内存区域划分的时候事实上是指JVM内存区域划分.在讨论JVM内存区域划分之前,先来看一下Java程序具体执行的过程:                                       如上图所示,首先Java源代码文件(.java后缀)会被Java编译器编译为字节码

深入理解JVM之三:垃圾回收算法

前言 垃圾收集算法是JVM中垃圾收集器的方法论,所以了解算法是必要的,在算法领域只做最简单的介绍,力求文章的简单易懂.垃圾收集算法主要有以下几种:标记-清除算法(mark-sweep).复制算法(copying)和标记-整理算法(mark-compact).随着jdk版本的升级,垃圾收集器也在不断的升级,现在最新的垃圾收集器已经能够对Java堆中一部分进行回收,也能够对Java堆中另一部分进行回收,这一成果在jdk1.7中得到体现.但是垃圾收集器的底层算法是深入垃圾收集器所必须了解的,这篇文章将

JVM性能优化系列

JVM性能优化(一)JVM技术入门 JVM 性能优化 (二)  编译器 JVM性能优化(三)垃圾收集 JVM性能优化(四)并发压缩GC JVM性能优化(五)可扩展性 转载自 并发编程网 - ifeve.com

JVM实用参数(六) 吞吐量收集器

原文链接 本文连接 译者:张军  校对:梁海舰 在实践中我们发现对于大多数的应用领域,评估一个垃圾收集(GC)算法如何根据如下两个标准: 吞吐量越高算法越好 暂停时间越短算法越好 首先让我们来明确垃圾收集(GC)中的两个术语:吞吐量(throughput)和暂停时间(pause times). JVM在专门的线程(GC threads)中执行GC. 只要GC线程是活动的,它们将与应用程序线程(application threads)争用当前可用CPU的时钟周期. 简单点来说,吞吐量是指应用程序线

JVM 内部运行线程介绍

感谢同事[觉梦]投递此稿. hi,all 最近抽时间把JVM运行过程中产生的一些线程进行了整理,主要是围绕着我们系统jstack生成的文件为参照依据.  前段时间因为系统代码问题,造成性能瓶颈,于是就dump了一份stack出来进行分析.  stack 里面线程非常多,排查起来需要一定的经验,所以,对它们有一定了解,可以提高排查问题的效率.  现在网上资料也不是特别全,所以,导致很多新人在拿到一个stack文件之后,也不知知道从何看起. 下面我把这次整理的一些个人认为比较常见的线程列出来. 线程