`

Java垃圾回收总结

阅读更多

 

一、在理解垃圾回收前需要了解一个对象在堆内存中的引用状态,分为三种:

1.可达状态:对象创建后,有一个或以上的引用变量引用它。

2.可恢复状态:程序中某个对象不再有任何引用变量引用它,但是还是有可能重新被其他引用变量引用。

3.不可达状态:对象与所用引用变量的引用都被切断,且jvm执行finalize()方法进行资源清理后没有成为可达状态,那么这个对象将永久的失去引用,编程不可达状态。(GC真正回收的正是处于这种状态的对象)。

 

public void test(){
     //此处对象为可达状态
     String a=new String("this is a string object");
     //此处a引用只想了另一个变量,则上面的string对象成为可恢复状态
     a=new String("another string object");
}

 

 

二、垃圾回收有如下机制:

1.垃圾回收只负责回收堆内存中的对象,不会回收任何物理资源(如:数据库连接,网络IO等)。

2.程序无法精确控制垃圾回收的运行,垃圾回收只有再合适的时候进行。对象成为不可达状态后,JVM会再合适的时候回收该对象。

3.垃圾回收任何对象前之前总会调用这个对象的finalize方法,进行资源清理。finalize方法可能使该对象重新成为可达状态,从而使使JVM取消对它的回收。

 

 

三、强制垃圾回收:

强制垃圾回收其实是建议JVM立即进行GC,但JVM是否进行gc操作是不确定的,垃圾回收机制只是在接收到通知尽快进行垃圾回收。强制垃圾回收有如下两种方式,

System.gc();

Runtime.getRuntime().gc();

 

 

四、理解finalize方法:

系统在垃圾回收前总会调用finalize方法进行资源清理,这个操作和垃圾回收操作是一起发生但要先于GC。只有程序任务需要额外的内存时才会进行GC。finalize有如下特点:

1.不要主动调用finalize方法,该方法应交给垃圾回收机制调用。

2.finalize方法何时执行无法确定。

3.JVM执行finalize方法时,有可能将对象从可恢复状态变成可达状态。

4.JVM执行finalize方法时,垃圾回收机制不会报错,程序继续执行。

如下例子说明垃圾回收的不确定性:

public class FinalizeTest {
	private static FinalizeTest ft=null;
	public void info(){
		System.out.println("调用系统的finalize方法");
	}
	
	public static void main(String[] args) throws InterruptedException {
		
		//创建对象语句也会进行垃圾回收
		new FinalizeTest();
		
		//通知系统立即进行垃圾回收
		System.gc();//1
		
		
//		Thread.sleep(2000);//3
		
		ft.info();
		
	}
	//重写了finalize方法
	public void finalize(){
		ft=this;
	}
}

 上述例子中注释掉3处代码可以发现程序报空指针异常,取消注释后,程序打印“ 调用系统的finalize方法”,说明程序显示执行垃圾回收,但finalize方法不会立即执行,当延迟2s后发现垃圾回收执行了。如果在1和3处代码中间加入下列代码则可强制调用finalize方法。

 

//强制垃圾回收调用可恢复对象的finalize方法,执行此方法前一定先通知系统进行垃圾回收操作
//		Runtime.getRuntime().runFinalization();
		System.runFinalization();//2

 

五、是否应该在程序中显示调用垃圾回收?

首先你需要知道两个概念:

JVM的gc有minor GC和major GC(也就是大家说的Full GC),JVM会很频繁的做minor GC,如果内存块占满的话,JVM会做Full GC,Full GC是对整个JVM内存堆做GC,所示耗时比minor GC要长很多。System.gc()最终执行的是Full GC
1,服务器老是崩溃是因为内存很快被占满,在允许的条件下你可以适当加大内存配置,用mx和ms控制内存堆大小
-Xms
-Xmx
2,如果你的程序需要通过System.gc()来减少JVM崩溃的几率,那么你的程序10有8,9存在问题,需要从你程序本身去进行优化
3,可以把GC配置为CMS回收方式,以提高回收效率
-XX:+UseConcMarkSweepGC
-XX:+UseParNewGC
-XX:+UseParNewGC
-XX:CMSFullGCsBeforeCompaction=0
-XX:CMSInitiatingOccupancyFraction=75
-XX:+CMSParallelRemarkEnabled
-XX:+CMSPermGenSweepingEnabled
-XX:+CMSClassUnloadingEnabled
4,-XX:+PrintGCTimeStamps  -XX:+PrintGCDetails -XX:+PrintHeapAtGC用这些参数输出GC日志,然后分析,

 

通过上述描述可知道,System.gc()最终执行的是Full GC,执行时会对整个JVM堆内存做GC,这将给程序带来一个严重的性能损失。一般不建议这么做。

 

六:为防止内存泄露,对象引用用完后都清空?

清空对象引用应该是一种例外,而不是一种规范行为,这样做会使代码很乱,一般而言只要类是自己管理内存,程序员就应该警惕内存泄露问题。

要防止内存泄露,下面是一些快速上手的实用技巧:
1. 当心集合类,比如 HashMap,ArrayList等,因为这是最容易发生内存泄露的地方.当集合对象被声明为static时,他们的生命周期一般和整个应用程序一样长。
2. 注意事件监听和回调.当注册的监听器不再使用以后,如果没有被注销,那么很可能会发生内存泄露.
3. "当一个类自己管理其内存空间时,程序员应该注意内存泄露." 常常是一个对象的成员变量需要被置为null 时仍然指向其他对象。

下面举一个模拟栈的例子:

public class Stack {
	private Object[] elements;
	private int size=0;
	private static int CAPACITY=16;
	public Stack(){
		elements=new Object[CAPACITY];
	}
	
	public void push(Object e){
		ensureCapacity();
		elements[size++]=e;
	}
	
	public Object pop(){
		if(size==0)
			throw new EmptyStackException();
		return elements[--size];
	}
		
	private void ensureCapacity(){
		if(elements.length==size){
			elements=Arrays.copyOf(elements, 2*size+1);
		}
	}
	
}

 此例子会有一个内存泄露的现象,从栈中弹出来的对象不会当做垃圾回收,即使栈不再引用这些对象,这是因为,栈内部还维护者这些弹出对象的过期引用。所谓过期引用是指永远不会被解除的引用。随着时间推移,无法回收对象越来越多,程序性能越来越差最后可能导致内存溢出。此时可以做如下处理:

 

       public Object pop2(){
		if(size==0)
			throw new EmptyStackException();
		Object result= elements[--size];
		elements[size]=null;
		return result;
	}

一旦数组元素变成非活动的一部分,就手动清空这些元素。

 

七、对象的软、弱和虚引用,

正常程序中的引用变量为强引用。当程序中需要避免在执行期间将对象留在内存中,可以使用如下几种引用:

1.软引用:当系统内存空间不足时,会回收它,但空间足够时,不会回收,程序也可以使用改对象。

2.弱引用:跟软引用类似,比软引用级别耕地,当GC操作时,不管内存是否足够,对象总会回收。

3.虚引用:和没有引用效果大致相同,主要用于跟踪对象垃圾回收状态,不能单独使用,必须和引用队列(ReferenceQueue)联合使用。

 

分享到:
评论

相关推荐

    Java垃圾回收机制总结

    Java垃圾回收机制总结 Java垃圾回收机制是Java虚拟机(JVM)中的一种机制,用于防止内存泄露和有效地使用空闲的内存。垃圾回收机制的主要目的是为了回收无用的对象占用的内存空间,使该空间可被程序再次使用。 ...

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

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

    Java垃圾回收原理

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

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

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

    Java垃圾回收机制

    Java垃圾回收机制的详细介绍,调理比较清晰,个人进行的总结。

    java高级之垃圾回收机制

    ### Java高级之垃圾回收机制详解 #### 一、引言 在现代软件开发中,Java因其平台无关性、丰富的库支持以及自动内存管理等特性,成为企业级应用开发的首选语言之一。其中,垃圾回收机制(Garbage Collection, GC)是...

    JAVA垃圾回收个人总结

    ### JAVA垃圾回收个人总结 #### 一、垃圾回收(GC)概述 垃圾回收(Garbage Collection,简称GC)是Java虚拟机(JVM)提供的一种自动内存管理机制,它负责自动回收不再使用的对象所占用的内存空间,从而避免了手动管理...

    java 垃圾回收机制详细介绍

    垃圾收集器是Java语言区别于其他程序设计语言的一大特色。它把程序员从手工回收内存空间的繁重工作中解脱了...鉴于此,笔者总结了这个垃圾收集器的专题,希望对广大Java技术的爱好者和准备认证考试的考生们有所帮助。

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

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

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

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

    JAVA垃圾回收个人总结.docx

    Java垃圾回收机制是Java编程中一个重要的概念,它主要用于自动管理程序运行时的内存,确保内存的有效利用并防止内存泄漏。垃圾回收主要关注Java堆和方法区,特别是堆区域,因为这是对象的主要存储区域。 垃圾收集器...

    Java与C#的垃圾回收机制

    ### Java与C#的垃圾回收机制 #### 一、引言 在现代编程语言中,内存管理是一项重要的功能,能够显著提升程序的稳定性和效率。本文将深入对比Java与C#这两种广泛使用的编程语言中的垃圾回收机制,帮助开发者更好地...

    Java 垃圾回收小结(一)

    本文将对Java垃圾回收进行小结,探讨其基本原理、类型以及常见算法。 1. 基本原理: Java中的内存分为堆(Heap)和栈(Stack)两部分,垃圾回收主要关注堆内存。当一个对象不再被任何引用指向时,它被视为可回收的...

    Java垃圾回收机制详解

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

    java垃圾回收以及jvm参数调优概述

    Java技术体系中所提倡的自动内存管理最终可以归结为自动化地解决了两个问题:给对象分配内存以及回收分配给对象...本文主要对java垃圾回收机制以及jvm参数等方面做个综述,也算是自己做开发这几年对这方面的一个总结。

    java垃圾回收(gc)机制详解

    总结,Java垃圾回收机制是Java平台的一个核心特性,它使得开发者无需关心内存管理细节,但理解其工作原理和优化策略对于提高应用性能至关重要。通过选择合适的GC类型,调整参数,以及良好的编程习惯,我们可以有效地...

Global site tag (gtag.js) - Google Analytics