`
cantellow
  • 浏览: 847329 次
  • 性别: Icon_minigender_1
  • 来自: 草帽海贼团
社区版块
存档分类
最新评论

Java垃圾回收器工作原理

    博客分类:
  • JVM
阅读更多

垃圾回收器是如何工作的?我现在就简单的介绍一下

首先要明确几点:

Java是在堆上为对象分配空间的

垃圾回收器只跟内存有关,什么IO啊,网络连接啊,管它P事

当可用内存数量较低时,Sun版本的垃圾回收器才会被激活

在垃圾回收器回收垃圾之前,我们先来了解一下Java分配对象的方式,Java的堆更像一个传送带,每分配一个新对象,它就往前移动一格。这意味着对象存储空间的分配速度相当快。Java的“堆指针”只是简单地移动到尚未分配的领域。也就是说,分配空间的时候,“堆指针”只管依次往前移动而不管后面的对象是否还要被释放掉。如果可用内存耗尽之前程序就退出就再好不过了,这样的话垃圾回收器压根就不会被激活。

但是由于“堆指针”只管依次往前移动,那么你肯定会想,总有一天内存会被耗尽,垃圾回收器就开始释放内存。这里有人肯定会问:怎么判断某个对象该被回收呢?答案就是当堆栈或静态存储区没有对这个对象的引用时,就表示程序(员)对这个对象没有兴趣了,它就应该被回收了。有两种方法来知道这个对象有没有被引用:第一种是遍历堆上的对象找引用;第二种是遍历堆栈或静态存储区的引用找对象。前者的实现叫做“引用计数法”,意思就是当有引用连接至对象时,引用计数加1,当引用离开作用域或被置为null时,引用计数减1,这种方法有个缺陷,如果对象之间存在循环引用,可能会出现“对象应该被回收,但引用计数却不为零”的情况。

Java采用的是后者,在这种方式下,Java虚拟机采用一种“自适应”的垃圾回收技术,如何处理找到的存活对象(也就是说不是垃圾),Java有两种方式:

一种是“停止-复制”:理论上是先暂停程序的运行(所以它不属于后台回收模式),然后将所有存活的对象从当前堆复制到另一个堆,没有被复制的全是垃圾。当对象被复制到新堆上时,它们是一个挨着一个的,所以新堆保持紧凑排列(这也是为什么分配对象的时候“堆指针”只管依次往前移动)。然后就可以按前述方法简单、直接地分配内存了。这将导致大量内存复制行为,内存分配是以较大的“块”为单位的。有了块之后,垃圾回收器就可以不往堆里拷贝对象了,直接就可以往废弃的块里拷贝对象了。

另一种是“标记-清扫”:它的思路同样是从堆栈和静态存储区出发,遍历所有的引用,进而找出所有存活的对象。每当它找到一个存活对象,就会给对象一个标记。这个过程中不会回收任何对象。只有全部标记完成时,没有标记的对象将被释放,不会发生任何复制工作,所以剩下的堆空间是不连续的,然后垃圾回收器重新整理剩余的对象,使它们是连续排列的。

当垃圾回收器第一次启动时,它执行的是“停止-复制”,因为这个时刻内存有太多的垃圾。然后Java虚拟机会进行监视,如果所有对象都很稳定,垃圾回收器的效率降低的话,就切换到“标记-清扫”方式;同样,Java虚拟机会跟踪“标记-清扫”效果,要是堆空间出现很多碎片,就会切换到“停止-复制”方式。这就是所谓的“自适应”技术。

其实仔细想一下,“停止-复制”和“标记-清扫”无非就是:“在大量的垃圾中找干净的东西和在大量干净的东西里找垃圾”。不同的环境用不同的方式,这样做完全是为了提高效率,要知道,无论哪种方式,Java都会先暂停程序的运行,所以,垃圾回收器的效率其实是很低的。Java用效率换回了C++没有的垃圾回收器和运行时的灵活,我认为这是明智的选择(虽然它只跟内存有关),随着硬件的飞速发展,我相信,开发时间要比运行效率重要得多!

分享到:
评论
3 楼 finux 2010-07-25  
C_J 写道
"当可用内存数量较低时,Sun版本的垃圾回收器才会被激活",貌似不准确

那应该是啥时候被激活进行垃圾回收呢?能用源码举例分析不罗,呵呵~
2 楼 finux 2010-07-25  
嘻嘻,写得不错,不过,貌似在<<Thinking in Java>>有看到过哦~
1 楼 C_J 2009-11-07  
文章不错,但有些地方有偏差..

"Java是在堆上为对象分配空间的",这个和C++的"堆"有所不同..

"当可用内存数量较低时,Sun版本的垃圾回收器才会被激活",貌似不准确

"如果对象之间存在循环引用,可能会出现“对象应该被回收,但引用计数却不为零”的情况",也许举个例子更容易理解..


很像当年的我~~

相关推荐

    Java垃圾回收原理

    ### Java垃圾回收原理详解 #### 一、引言 在现代软件开发中,Java作为一种广泛使用的编程语言,其垃圾回收机制是确保程序高效运行的关键技术之一。本文将深入探讨Java中的垃圾回收机制,包括其基本原理、不同类型...

    Java垃圾回收机制

    本文将深入探讨Java垃圾回收机制的核心原理及其关键技术。 #### 二、Java堆内存 Java的堆是一个运行时数据区,用于存储所有对象实例。这些对象是通过`new`、`newarray`、`anewarray`和`multianewarray`等指令创建...

    java垃圾回收器代码举例

    本篇文章将通过代码示例和个人笔记来深入探讨Java垃圾回收器的工作原理及其应用。 1. **Java内存模型** - Java内存分为堆内存(Heap)和栈内存(Stack)。堆内存主要存储对象实例,而栈内存则存储方法调用时的局部...

    java高级之垃圾回收机制

    本文将详细介绍Java中的垃圾回收机制及其工作原理,并探讨JVM如何管理和优化垃圾回收过程。 #### 二、JVM内存模型 JVM内存模型主要包括永久代(Permanent Generation, PermGen)、堆(Heap)和栈(Stack)三大部分。值得...

    细述 Java垃圾回收机制→How Java Garbage Collection Works- - Android 1

    本文将详细介绍Java垃圾回收机制的工作原理、各个阶段的执行过程、不同的垃圾回收器类型、Java中的引用类型等。 Java垃圾回收机制的工作原理 ------------------------- Java垃圾回收机制的工作原理是,当一个对象...

    Java垃圾回收详解

    ### Java垃圾回收详解 #### 垃圾回收基础概念 在Java编程语言中,垃圾回收(Garbage Collection, GC)是一项自动化的内存管理机制。它能够自动检测并释放那些不再被程序使用的对象所占用的内存空间,从而有效地...

    细述 Java垃圾回收机制→Java Garbage Collection Introduction - Android 1

    这篇文章将会介绍Java垃圾回收机制的基本概念和原理,包括JDK、JVM、JRE、HotSpot VM等基本术语,以及JVM的架构和Java堆内存结构。 Java术语: * Java API:一个帮助程序员创建Java应用的打包好的库集合 * JDK...

    JVM垃圾回收器工作原理及使用实例介绍Java开发Java

    理解并掌握JVM垃圾回收器的工作原理对于Java开发者来说至关重要,这有助于编写出更高效、稳定的代码,避免因内存问题导致的程序崩溃。通过实践和不断优化,开发者可以提升应用的性能,提供更好的用户体验。

    Java垃圾回收机制的学习和使用

    Java垃圾回收机制是Java编程中至关重要的一部分,它自动管理内存,释放不再使用的对象,避免内存泄漏,并优化内存使用。Java虚拟机(JVM)的堆内存是存放对象的主要区域,当对象通过new等指令创建后,垃圾回收机制...

    Java与C#的垃圾回收机制

    本文将深入对比Java与C#这两种广泛使用的编程语言中的垃圾回收机制,帮助开发者更好地理解它们的工作原理以及差异。 #### 二、Java的垃圾回收机制 ##### 2.1 Java内存区域 Java虚拟机(JVM)将内存划分为几个主要...

    详细介绍Java垃圾回收机制

    Java垃圾回收机制是Java编程语言的关键特性,负责自动管理程序中的内存,确保程序高效、稳定地运行。在Java虚拟机(JVM)中,垃圾回收的主要任务是识别并清理不再被程序使用的对象,以避免内存泄漏。以下是关于Java...

    JAVA垃圾回收面试个人总结.doc

    Java垃圾回收机制是Java编程中一个非常重要的概念,尤其在面试和实际开发中常常被讨论。垃圾回收(Garbage Collection, GC)是Java虚拟机自动管理内存的一种方式,旨在自动识别并释放不再使用的对象,从而避免内存...

    Java垃圾回收机制详解

    ### Java垃圾回收机制详解 #### 一、引言 在软件开发领域,特别是对于像Java这样的面向对象语言,内存管理一直是开发者关注的核心问题之一。Java的出现极大地简化了这一过程,其中最为突出的特点之一就是其内置的...

Global site tag (gtag.js) - Google Analytics