您的位置:首页 > 编程语言 > Java开发

Java中的垃圾回收机制

2017-02-08 12:41 190 查看
内存泄漏:传统的C/C++等编程语言,需要程序员自己负责回收已经分配的内存。显式进行垃圾回收是一件比较困难的事情,程序员并不总是知道内存应该在什么时候被释放。如果一些分配出去的内存得不到及时的回收,就会引起系统运行速度下降,有时甚至会导致程序瘫痪,这样的现象就叫做内存泄漏。

显式进行垃圾回收有如下的缺点:

程序忘记及时回收无用内存,从而导致内存泄漏,降低系统性能。

程序错误的回收程序核心类库的内存,从而导致系统崩溃。

和C/C++程序不同,Java语言不需要程序员直接控制内存回收,Java程序的内存分配和回收都是由jre在后台自动进行的。jre会自己负责那些不在使用的内存,这种机制就叫做垃圾回收。通常情况下,jre会提供后台线程来进行检测和控制,一般都是在CPU空闲的时候或者内存不足的时候自动的进行垃圾回收,程序员是无法精确控制垃圾的回收时间和顺序等等。

Java的堆内存是一个运行时数据区,用以保存类的实例,即对象。Java虚拟机的堆内存中存储着正在运行的应用程序所建立的所有对象,这些对象不需要程序通过代码来显示的进行释放。一般来说,堆内存的回收是由垃圾回收来负责的,所有的jvm实现都有一个由垃圾回收器管理的堆内存。垃圾回收是一种动态存储管理技术,它自动的释放不被程序引用的对象。按照特定的垃圾回收算法来实现内存资源的自动回收功能。

在C/C++中,对象所占的内存在程序结束运行之前一直被占用,被明确释放之前不能分配给其他对象,但是在Java中,当该对象不再被引用时,该内存就会成为垃圾。jvm的一个超级线程就会自动释放该内存区域。垃圾回收意味着程序不再需要的对象是垃圾信息,这些信息就会被丢弃。

当一个对象不再被引用时,内存会回收它所占领的空间,以便于空间被后来的新对象使用。事实上,除了释放没用的对象以外,垃圾回收也可以清除内存记录碎片。由于创建对象和垃圾回收器释放丢弃对象所占的内存空间,内存会出现碎片,碎片是分配给对象的内存块之间的空闲内存区,碎片整理将所占用的堆内存移到了堆得另一端,jvm将整理出的内存分配给新的对象。

垃圾回收能自动释放内存空间,减轻编程的负担。这使jvm虚拟机具有两个显著地优点。垃圾回收机制能够很好地提高编程的效率,在没有垃圾回收机制时,可能就要花上许多的时间来解决一个难懂的存储器问题。再用Java编程时,依靠垃圾回收机制能够大大的缩短时间。

缺点:垃圾回收的一个潜在的缺点就是他的开销影响性能。Java虚拟机必须跟踪程序中有用的对象,这样才可以确定哪些是无用的对象,并最终释放该对象。这个过程是需要花费处理器的时间的。另外,垃圾回收算法不完备,不能保证100%收集到所有的废弃内存。

垃圾回收的特点:

1,垃圾回收机制的工作目标是回收无用的对象的内存空间,这些内存空间都是jvm堆内存的内存空间,垃圾回收只能回收内存空间,对其他的硬件资源是不能解决问题的。

2,为了更够更快的让垃圾回收机制回收那些不再被使用的对象,可以将该对象设置为null,可以通过这种方式来暗示垃圾回收机制回收该对象。

3,垃圾回收的不可预知性。不同的jvm采用的垃圾回收机制和垃圾回收算法是不相同的。因此,有可能是定时发生的,也有可能是CPU空闲的时候发生的,也有可能和原始的垃圾回收机制一样,等到内存消耗到极限时发生。这和垃圾回收机制的选择及具体的设置都有关系。虽然可以通过调用对象的finalize()方法或者System.gc()等方法来建议系统进行垃圾回收,但是这种方法并不能精确地控制垃圾回收机制的执行。

4,垃圾回收机制的精确性主要包括两个方面:一,垃圾回收机制能够精确地标记活着的对象;二,垃圾回收器能够精确地定位对象之间的引用关系。前者是完全回收所有废弃对象的前提。否则就会造成内存泄漏;后者则是实现归并和复制等算法的必要条件,通过这种引用关系,可以保证所有的对象都能够被可靠地回收,所有对象都能够被重新分配,从而有效的减少内存碎片的产生。

5,现在的jvm有多种不同的垃圾回收实现,每种回收机制因为算法的差异可能会表现不同,有的是当垃圾回收开始时就停止应用程序的运行,有的当垃圾回收运行时允许应用程序的线程运行。还有的同一时间允许垃圾回收多线程运行。

在编写Java程序时,一个基本的原则就是:对于不再需要的对象,不要在引用他们。如果保持这些对象的引用,垃圾回收机制就会暂时不回收该对象,这样就会导致系统可用的内存越来越少,当系统可用内存越来越少时,垃圾回收执行的频率就越来越高,从而导致系统的性能下降。

本文参考自:李刚版《Java疯狂讲义第二版》,有兴趣的可以自己看一下
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: