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

Java中垃圾回收机制

阅读更多

1、什么是垃圾 

        垃圾,内存中的垃圾,即内存中已无效但又无法自动释放的空间。在Java 语言中,没有引用句柄指向的类对象最容易成为垃圾。产生垃圾的情况有很多,主要有以下3 种: 

 

(1)超出对象的引用句柄的作用域时,这个引用句柄
引用的对象就变成垃圾。 

例1 
{  

 

   Person p1 = new Person(); 

 


 …… } 


         引用句柄p1 的作用域是从定义到“}”处,执行完这对大括号中的所有代码后,产生的Person 对象就会变成垃圾,因为引用这个对象的句柄p1 已超过其作用域,p1 已经无效,Person 对象不再被任何句柄引用了。   

(2)没有超出对象的引用句柄的作用域时,给这个引
用句柄赋值为空时,这个引用句柄引用的对象就变成垃圾。 

例2 
{  

      Person p1 = new Person(); 
 ….. 

 p1 = null; 
 …. } 

          在执行完“p1=null;”后,即使句柄p1 还没有超出其作用域,仍然有效,但它已被赋值为空,不再指向任何对象,则这个Person 对象不再被任何句柄引用,变成了垃圾。此后p1 还可以指向其它Person 对象,因为还没有超出它的作
用域。 

(3)创建匿名对象时,匿名对象用完以后即成垃圾。 

例3 

   new Person();  // 因为是匿名对象,没有引用句柄指向它,即为垃圾 
   new Person().print(); //当运行完匿名对象的print()方法,这个对象也变成了垃圾 
    …… 


因此,在程序中应尽量少用匿名对象。
 

 

2 、 垃圾回收 

 

 

       在 Java 程序运行过程中,一个垃圾回收器(Garbage Collector,简称GC)会不定时地被唤起检查是否有不再被使用的对象,并释放它们占用的内存空间。垃圾回收器的回收无规律可循,可能在程序的运行的过程中,一次也没有启动,也可能启动很多次。因此,并不会因为程序代码一产生垃圾,垃圾回收器就马上被唤起而自动回收垃圾,很可能到程序结束时垃圾回收器都没有启动。所以垃圾回收器并不能完全避免内存泄漏的问题。

       另一方面,垃圾回收会给系统资源带来额外的负担和时空开销。它被启动的几率越小,带来的负担的几率就越小。因此,垃圾的回收策略也很重要。 

 

3、 垃圾回收器的回收策略 
       不同厂商、不同版本的Java 虚拟机中的内存垃圾回收机制并不完全一样,通常越新版本的内存回收机制越快。而不同的Java 虚拟机采用不同的回收策略,常用的有两种:复制式回收策略和自省式回收策略。 

        复制式回收策略:先将正在运行中的程序暂停,然后把正在被使用的所有对象从它们所在的堆内存A 里复制到另一块堆内存B,再释放堆内存A 中的所有空间,这些不再使用的对象所占用的内存空间就会被释放掉。这种方式需要维护所需内存数量的至少两倍的内存空间,适合垃圾比较多的情况。当程序只产生了少量垃圾或者没有垃圾时,这种回收策略的效率就非常低。

        自省式回收策略:首先检测所有正在使用的对象,并为它们标注,比如用1 来标注正在使用的对象,用0 来标注不再被使用的对象,然后将所有标注为 0 的内存空间一次释放。因为标注会增大系统的开销,因此这种方式的速度仍然很慢,尤其是在垃圾比较多的情况下,效率会很低。这种方法适合垃圾比较少的情况。

        这两种方式具有互补性,因此在一些Java 虚拟机中两种方式被有机的结合运用。 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics