`
baitian
  • 浏览: 30172 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

关于java 垃圾回收的理解

阅读更多
垃圾回收分为两大步骤:识别垃圾 和 回收垃圾
识别垃圾有两大基本方法
1.计数器法
每个对象有一个相应的计数器,统计当前被引用的个数,每次被引用或者失去引用都会更新该计数器。
优点:识别垃圾快,只需判断计数器是否为零。
缺点:增加了维护计数器的成本,无法在对象互相引用的情况下识别垃圾
因此,适用于对实时性要求非常高的系统。
2.追踪法
从根对象(例如局部变量)出发,逐一遍历它的引用。若无法被扫描到,即认定为垃圾
实际情况中一般采用该方法。

回收垃圾最重要的是要最大限度地减少内存碎片。
两种通常的方法:
1.移动活对象覆盖内存碎片,使对象间的内存空白增大。
2.拷贝所有的活对象到另外一块完整的空白内存,然后一次释放原来的内存。

通常第二种方法能够最大的减少内存碎片,但是缺点是在拷贝过程中会终止程序的运行。
引入分级的概念,通常一个程序中大部分对象的生命周期很短,只有小部分的对象有比较长的生命。而恰恰使得拷贝方法性能打折扣的是重复拷贝那些长命的对象。因此,把对象分成几个级别,在低级别呆到一定时间就将其升级。相应地越高级别,回收的次数越少。最理想的情况是,每次回收最低级别的对象全部失效,一次性就可以回收该级别所有内存,提高效率。同时,由于每次只回收一个级别,不需遍历所有对象,控制了整个回收的时间。

由于垃圾识别是通过识别引用来达到,为了增加程序对垃圾回收的控制。提供了引用对象的概念,细化了引用的类型,分别是StrongReference,SoftReference, WeakReference, PhantomReference。其中强引用就是普通的java引用,其他三种类型相当于一个包装器,一方面使得垃圾回收器区分引用类型做不同的处理,另一方面程序通过他们仍然可以得到强引用。
这三种弱类型的类的结构图:


因此一个对象在它的生命周期可能有以下几种状态:strongly reachable,softly reachable,weakly reachable,resurrectable,phantom reachable,unreachable。
引用

    strongly reachable - An object can be reached from the roots without traversing any reference objects. An object begins its lifetime in the strongly reachable state and remains strongly reachable so long as it is reachable via a root node or another strongly reachable object. The garbage collector will not attempt to reclaim the memory occupied by a strongly reachable object.
    softly reachable - An object is not strongly reachable, but can be reached from the roots via one or more (uncleared) soft reference objects. The garbage collector may reclaim the memory occupied by a softly reachable object. If it does so, it clears all soft references to that softly reachable object. When the garbage collector clears a soft reference object that is associated with a reference queue, it enqueues that soft reference object.
    weakly reachable - An object is neither strongly nor softly reachable, but can be reached from the roots via one or more (uncleared) weak reference objects. The garbage collector must reclaim the memory occupied by a weakly reachable object. When it does so, it clears all the weak references to that weakly reachable object. When the garbage collector clears a weak reference object that is associated with a reference queue, it enqueues that weak reference object.
    resurrectable - An object is neither strongly, softly, or weakly reachable, but may still be resurrected back into one of those states by the execution of some finalizer.
    phantom reachable - An object is not strongly, softly, nor weakly reachable, has been determined to not be resurrectable by any finalizer (if it declares a finalize() method itself, then its finalizer will have been run), and is reachable from the roots via one or more (uncleared) phantom reference objects. As soon as an object referenced by a phantom reference object becomes phantom reachable, the garbage collector will enqueue it. The garbage collector will never clear a phantom reference. All phantom references must be explicitly cleared by the program.
    unreachable - An object is neither strongly, softly, weakly, nor phantom reachable, and is not resurrectable. Unreachable objects are ready for reclamation.

对照下面这张图来理解:


这三种弱引用的应用场合:
引用
Weak references enable you to create canonicalizing mappings, such as a hash table whose keys and values will be removed from the map if they become otherwise unreferenced by the program.

典型应用,jdk 的 WeakHashMap, ThreadLocal.

引用
Soft references enable you to create in-memory caches that are sensitive to the overall memory needs of the program. 

Phantom references enable you to establish more flexible pre-mortem cleanup policies than are possible with finalizers.



参考:
1.http://www.artima.com/insidejvm/ed2/gcP.html
2.http://www.iteye.com/topic/401478
分享到:
评论
16 楼 葬雪晴 2011-05-11  
lifeier 写道
扯这些有什么鬼用,开发中又用不着。

鄙视这种自己不会,就乱喷的人。

补充一点,我理解的垃圾回收机制。

在JAVA语言里,有自动的回收机制,让我们能很轻松的不用去理会垃圾回收,而能轻松的编程。
不像C++一样,还要去析构,不去析构就会内存溢出然后头痛的很。

JAVA里的垃圾回收机制,用的是类似有向图的监控,当一个对象完全没有了指向这个对象的引用的时候,垃圾回收机制会帮忙回收。。。由于启动垃圾回收器需要花费资源,所以不是说你想启动就启动的。所以只能是建议System.GC()

所以很多新手就认为,都机器做了垃圾回收机制,我们不需要去管,其实那只是新手的一厢情愿。

JAVA也有内存溢出,在进行队列的删除的时候如果由于只是在标记位上删除,而数组本身的某个引用还是有对象的,于是这个引用永远都不会回收。于是会造成内存溢出。

哈哈,大家多多包涵
15 楼 suhuanzheng7784877 2011-05-10  
个人觉得垃圾回收的原理还是需要知道的啊~~~~
是这样的~~
有时候确实对象在内存中的状态、周期是需要知道的~
而且弱引用、软引用等等都是在一定场合下派得上用场的~~~
一旦应用报出了内存溢出的异常也好排错嘛~
呵呵~~
http://suhuanzheng7784877.iteye.com/blog/1000646
这个希望对LZ也能有所帮助~
14 楼 laolinshi 2011-05-10  
lifeier 写道
扯这些有什么鬼用,开发中又用不着。

这只能说明你还停留在民工的水平。
13 楼 liuxuejin 2011-05-09  
解释得实在有点简单
12 楼 jwx0925 2011-05-08  
lifeier 写道
扯这些有什么鬼用,开发中又用不着。


水平低,还用不到吧~
11 楼 Rooock 2011-05-08  
关于java里的几种引用, 我觉得这篇文章言简意赅.
10 楼 safrain 2011-05-07  
lifeier 写道
扯这些有什么鬼用,开发中又用不着。

有一些场合会用到的。
9 楼 niwei 2011-05-06  
你执行一下下面的代码,将虚拟机参数设置如下:
-Xms15m -Xmx15m -Xmn10m -XX:+UseSerialGC -XX:+PrintGCDetails

public static void main(String[] args) throws Exception
	{
		byte[] b = new byte[1024 * 1024 * 5];
		SoftReference sr = new SoftReference(b);
		b = null;

		byte[] b2 = new byte[1024 * 1024 * 5];

		byte[] b3 = new byte[1024 * 1024 * 5];

		if (sr == null)
		{
			System.out.println("1");
		}
		else if (sr.get() == null)
		{
			System.out.println("2");
		}
		else
		{
			System.out.println("3");
		}
	}


你会发现在执行FullGC之后sr!=null,但sr.get()==null
8 楼 niwei 2011-05-06  
Technoboy 写道
niwei 写道
因为你已经将image置为null,有可能因为被垃圾回收而get()不到了,避免空指针。

将image设置为null,就是让GC知道,让SoftReference保存image引用,当GC检测到会抛出OutOfMemoryError时,会清理软引用,此时的image才真正的为空,并需要重新创建对象。


我的意思是你将image设置为null之后再获取时最好将(sr!=null && sr.get()!=null) 这两个判断条件都加上,因为你再次使用时可能sr!=null 但 sr.get()==null。
7 楼 Technoboy 2011-05-06  
niwei 写道
因为你已经将image置为null,有可能因为被垃圾回收而get()不到了,避免空指针。

将image设置为null,就是让GC知道,让SoftReference保存image引用,当GC检测到会抛出OutOfMemoryError时,会清理软引用,此时的image才真正的为空,并需要重新创建对象。
6 楼 niwei 2011-05-06  
因为你已经将image置为null,有可能因为被垃圾回收而get()不到了,避免空指针。
5 楼 Technoboy 2011-05-06  
baitian 写道
引用

//下次使用时
if (sr!=null) image=sr.get();
else{
//由于GC由于低内存,已释放image,因此需要重新装载;
image=new Image();
sr=new SoftReference(image);
}


if (sr!=null && sr.get()!=null)
else{
image=new Image();
sr=new SoftReference(image);
}

这样才准确把。

if判断是干啥用的呢?
4 楼 baitian 2011-05-06  
引用

//下次使用时
if (sr!=null) image=sr.get();
else{
//由于GC由于低内存,已释放image,因此需要重新装载;
image=new Image();
sr=new SoftReference(image);
}


if (sr!=null && sr.get()!=null)
else{
image=new Image();
sr=new SoftReference(image);
}

这样才准确把。
3 楼 Technoboy 2011-05-06  
lifeier 写道
扯这些有什么鬼用,开发中又用不着。

假如实现一些常用图片的缓存功能:

//申请一个图像对象
Image image=new Image();//创建Image对象

//使用 image

//使用完了image,将它设置为soft 引用类型,并且释放强引用;
SoftReference sr=new SoftReference(image);
image=null;

//下次使用时
if (sr!=null) image=sr.get();
else{
//由于GC由于低内存,已释放image,因此需要重新装载;
image=new Image();
sr=new SoftReference(image);
}

这样写,不是better一些。


2 楼 baitian 2011-05-05  
lifeier 写道
扯这些有什么鬼用,开发中又用不着。

呵呵,见谅啊!
1 楼 lifeier 2011-05-05  
扯这些有什么鬼用,开发中又用不着。

相关推荐

    Java垃圾回收详解

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

    java垃圾回收器代码举例

    总之,理解并掌握Java垃圾回收机制对于编写高效、稳定的Java程序至关重要。通过实践和调整,我们可以有效地利用内存资源,提高应用的运行效率。在实际项目中,选择合适的垃圾回收器和调优策略是提升系统性能的关键。

    Java垃圾回收原理

    通过深入理解Java垃圾回收的原理和技术,开发者可以更好地优化自己的代码,提高程序的性能和稳定性。不同的垃圾回收器有着各自的特点和适用场景,合理选择和配置垃圾回收器对于提升应用的整体表现至关重要。 Java的...

    Java垃圾回收机制

    ### Java垃圾回收机制详解 #### 一、Java垃圾回收机制概览 Java作为一种现代的、面向对象的编程语言,其一大特色就是引入了自动垃圾回收机制。这一特性极大地简化了开发人员的工作,使得他们不再需要手动管理内存...

    理解Java垃圾回收

    理解Java垃圾回收机制对于编写高效、健壮的Java程序至关重要。开发者需要了解垃圾回收的工作原理,避免产生内存泄漏,并合理调整垃圾回收参数以适应应用程序的需求。在实际开发中,结合内存分析工具(如VisualVM、...

    java垃圾回收及内存泄漏.pptx

    ### Java垃圾回收及内存泄漏知识点详解 #### 一、Java内存管理 1. **运行时数据区**:Java虚拟机管理的内存主要分为以下几个部分: - **方法区(Method Area)**:存储类的信息(如类名、字段、方法等)、常量、...

    JAVA垃圾回收机制

    Java垃圾回收机制(GC)是Java编程语言的关键特性,它自动管理内存,释放不再使用的对象,以防止内存泄漏。GC的运作方式主要有两种策略:引用计数和对象引用遍历。 引用计数是一种简单但不完美的方法。每个对象都有...

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

    在阿里巴巴这样的大型公司校招中,深入理解Java垃圾回收机制是衡量候选人技术能力的重要标准,因为这直接影响到系统性能和稳定性。因此,对于求职者来说,深入学习和掌握这些知识是非常有益的。

    java高级之垃圾回收机制

    通过深入理解JVM内存模型以及不同的垃圾回收算法,可以帮助我们更好地优化程序性能,提高代码质量。在实际开发过程中,合理利用JVM提供的工具和技术,可以有效地避免内存泄漏等问题,提升系统的稳定性和可靠性。

    java垃圾回收

    Java垃圾回收(Garbage Collection, 简称GC)是Java虚拟机(JVM)管理内存的一种机制,它自动地识别并清理不再使用的对象,从而避免了程序员手动管理内存可能导致的内存泄漏问题。垃圾回收是Java语言的一个重要特性...

    java垃圾回收技术,面试会问

    ### Java垃圾回收技术详解 #### 一、引言 在现代软件开发中,Java作为一种广泛使用的编程语言,其垃圾回收机制(Garbage Collection, GC)是面试和技术交流中经常提及的话题之一。尤其对于那些深入研究Java内存...

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

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

    Java垃圾回收精粹-Part4Java开发Java经验技

    总结,理解并掌握Java垃圾回收机制是提升Java应用程序性能的关键。通过选择合适的垃圾回收器、合理调整参数以及遵循良好的编程实践,我们可以有效管理内存,减少系统停顿,提高应用的稳定性和响应速度。

    搞定面试官:咱们从头到尾再说一次 Java 垃圾回收(csdn)————程序.pdf

    Java垃圾回收机制是Java虚拟机(JVM)中一个至关重要的功能,它负责自动管理内存,释放不再使用的对象,防止内存泄漏,从而优化程序性能。本文将深入探讨Java垃圾回收的相关知识点。 首先,GC(Garbage Collection...

    Java垃圾回收知识,垃圾回收资料

    理解并掌握Java垃圾回收机制,不仅有助于解决内存溢出、性能瓶颈等问题,还能在面试中展现对Java内存管理的深入理解。对于开发者来说,熟练运用各种GC算法和收集器,以及掌握调优技巧,是提升代码质量和系统性能的...

    java内存管理与垃圾回收

    Java 内存管理与垃圾回收是Java编程中至关重要的概念,它们确保了程序的稳定运行和内存的有效利用。Java在JVM(Java Virtual Machine)上运行,内存主要分为两个主要区域:栈(Stack)和堆(Heap)。 栈主要用于...

    Java与C#的垃圾回收机制

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

Global site tag (gtag.js) - Google Analytics