java语言中的垃圾回收机制_第1页
java语言中的垃圾回收机制_第2页
java语言中的垃圾回收机制_第3页
java语言中的垃圾回收机制_第4页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

java语言中的垃圾回收机制

java是描述平台应用的面向的编程语言,由sun微软系统的詹姆斯斯林和其他人于20世

纪90年代初开发。伴随着Java技术的普及,网络上越来越多的服务器程序采用Java技

术,特别是Internet使Java成为网上最流行的编程语言。在传统的高级编程语言(例

C++)中,对象的创建和回收均由程序员自行负责,如果创建了对象而忘记回收,则会造

成内存泄漏,长此以往,程序运行的时候可能会生成很多不清除的垃圾,浪费了不必要的

内存空间,有时还可能引起系统的崩溃。在Java中,引入了垃圾回收机制:垃圾回收器

(GarbcigeCollector,GC),可以自动回收内存中的垃圾,这是Java语言相对于其它语

言的优势,但是内存泄漏并不会因此而完全避免。

1自动的垃圾回收机制

大多数C++编译器不支持垃圾I可收机制。通常使用C++编程的时候,程序员所创建的对象

在创建时在堆栈上分配一块内存地址,当不需要这个对象,进行析构或者删除的时候再释

放分配的内存空间。如果对象是在堆上分配了,而程序员乂忘记进行释放,这些空间乂无

法自动回收,就会造成内存泄漏。而无法回收的内存空间,即丢失的内存(称为“垃

圾”),除非是重新启动系统否则永远也不会还给操作系统。长此以往,程序运行的时候

可能会生成很多垃圾,浪费了不必要的内存空间。更糟糕的是,如果同一内存地址被删除

两次的话,程序会变得不稳定,甚至崩溃。

Java语言则不同,上述的情况被自动垃圾问收机制自动处理。对象的建立和放置都是在内

存堆栈上面进行的。程序或者其他的对象可以锁定一块堆栈地址来进行其他对象的引用。

当一个对象没有任何引用的时候,Java的自动垃圾回收机制就发挥作用,自动删除这个对

象所占用的空间,释放内存以避免内存泄漏。但是内存泄漏并不是就此而完全避免了,当

程序员疏忽大意地忘记解除一个对象不应该有的引用的时候,内存泄漏仍然不可避免,不

过发生的几率要比不启用垃圾回收机制的C++程序少很多。但是总体来讲,自动垃圾回收

机制要安全和简单许多。

2垃圾回收机制

2.1引用对象已经超过其作用域

垃圾,内存中的垃圾,即内存中已无效但又无法自动释放的空间。在Java语言中,没有

引用句柄指向的类对象最容易成为垃圾。产生垃圾的情况有很多,主要有以下3种:

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

例1

引用句柄pl的作用域是从定义到“}”处,执行完这对大括号中的所有代码后,产生的

Person对象就会变成垃圾,因为引用这个对象的句柄pl已超过其作用域,pl已经无效,

Person对象不再被任何句柄引用了。

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

引用的对象就变成垃圾。

例2

在执行完"Pl=null;"后:即使句柄D1还没有超出其作用域,,仍然有效,但它已被赋值

为空,不再指向任何对象:则这个Person对象不再被任何句柄引用,变成了垃圾。此后

P1还可以指向其它Person对象,因为还没有超出它的作用域。

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

例3

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

2.2释放内存空间

在Java程序运行过程中,一个垃圾回收器(GarbageCollector,简称GC)会不定时地被

唤起检杳是否有不再被使用的对象,并释放它们占用的内存空间。垃圾回收器的回收无规

律可循,可能在程序的运行的过程中,一次也没有启动,也可能启动很多次。因此,并不

会因为程序代码一产生垃圾,垃圾回收器就马上被唤起而自动回收垃圾,很可能到程序结

束时垃圾回收器都没有启动。所以垃圾回收器并不能完全避免内存泄漏的问题。

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

来的负担的几率就越小。因此,垃圾的回收策略也很重要。

2.3次释放型内存空间

不同厂商、不同版本的Java虚拟机中的内存垃圾回收机制并不完全一样,通常越新版本

的内存回收机制越快。而不同的Java虚拟机采用不同的回收策略,常用的有两种:复制式

回收策略和自省式回收策略。

复制式回收策略:先将正在运行中的程序暂停,然后把正在被使用的所有对象从它们所在

的堆内存A里复制到另一块堆内存B,再释放堆内存A中的所有空间,这些不再使用的对

象所占用的内存空间就会被释放掉。这种方式需要维护所需内存数量的至少两倍的内存空

间,适合垃圾比较多的情况。当程序只产生了少量垃圾或者没有垃圾时,这种回收策略的

效率就非常低。

自省式回收策略:首先检测所有正在使用的对象,并为它们标注,比如用1来标注正在使

用的对象,用0来标注不再被使用的对象,然后将所有标注为0的内存空间一次释放。因

为标注会增大系统的开销,因此这种方式的速度仍然很慢,尤其是在垃圾比较多的情况下,

效率会很低。这种方法适合垃圾比较少的情况。

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

由于Java的垃圾回收器的启用不由程序员控制,而且同收也无规律可循,并不会一产生

了垃圾,垃圾回收器就被唤起;有时甚至可能到程序终止,回收器都没有启动的机会。因

此这个垃圾回收机制不是一个很可靠的机制。因为垃圾不能及时回收,它们所占用的内存

空间不能释放,就会影响程序的性能;如果某段程序产生大量的垃圾而没有回收,回收工

作也会变得困难。为了解决这个问题,Java提供一个Sys吐川.gc()方法,可以强制启动

垃圾回收器来回收垃圾,以减少内存泄露发生的概率。

例4匿名对象会产生垃圾:如果担心这些垃圾不能及时回收,可以在使用完这些匿名对象

以后,加上一条语句:System,gc(),强制启动垃圾回收器来回收垃圾。

程序的运行结果如图2所示。

System,gc()有一个特点,就是在对象被当成垃圾从内存中释放前要调用finalize()

方法,而且释放一个对象调用一次finalize()方法。从程序的运行结果可以看到:泣圾

回收器后动以后,井不一定马上回收垃圾,很可能要等待一段时间才执行。这是因为在程

序运行过程中,垃圾收集线程优先级比较低,如果有比这个线程优先级高的线程,先运行

这些优先级高的线程,等这些线程执行完毕,才进行垃圾回收。所以System,gc()方法

只是一种“建议”,它建议Java虚拟机执行垃圾回收,释放内存空间,但不能够预知什

么时候能够回收。

如果把“System,gc();"语句,放在第二个匿名对象语句后面,再进行编译和执行,其

结果将如图3所示。

这是因为,启动完垃圾回收器以后,它只能检测到在垃圾回收器强制启动之前程序运行所

产生的垃圾,Java的虚拟机尽最大的努力从被丢弃的对象上回收垃圾;对于在启动垃汲回

收器以后产生的垃圾,这个线程检测到的概率就非常小了,如果检测不到,就不能回收这

些垃圾。

因此,Java中的垃圾回收器机制及System,gc()方法,并不能够完全避免内存泄露的问

题,只是尽可能降低内存泄露的可能性和程度。

4java编程中应该注意的问题

为了提高垃圾的回收效率:在实际应用中,使用卜列几种方法可以在一定程度上避免Java

中的内存泄露。

(1)尽量利用公开对象,忽视内部模式

匿名对象被使用完以后就会变成垃圾;而在内部类中,隐含着一个外部类对象的引用,这

个引用也无法自动消除。

(2)调用tableity方法

因为System,gc()方法在回收每一个对象所占用的内存空间时,都会调用finalize()

方法,在这个方法中的任何操作都会增加垃圾回收的开销。

(3)启动垃圾回收

在程序中可以显式地调用System,gc()方法,但这种方法不能保证清除所有的垃圾。另

外垃圾回收也是一个线程,也会消耗系

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论