论文部分内容阅读
摘要:垃圾收集是Java语言区别于其他程序设计语言的一大特色。但是目前多数的Java书籍有关垃圾收集的内容几乎没有或只做了非常简单的介绍。本文从多个方面分析了Java的垃圾回收机制,使学习者能够对该机制产生一个全面的认识。
关键词:Java虚拟机;垃圾收集;垃圾收集器
中图分类号:TP311.1 文献标识码:A文章编号:1007-9599 (2011) 01-0000-01
Comprehensive Analysis of Java Garbage Collection Mechanism
Xu Xiaolong
(Institute of Computer Science,Qufu Normal University,Rizhao276826,China)
Abstract:Garbage collection is a java language feature which is different from other programming languages.But most current Java books relevant garbage collection content almost no or do only very simple introduction.This paper analyzes the java garbage collection mechanism from several aspects.Learners can generates a comprehensive understanding of the mechanism.
Keywords:JVM;Garbage collection;Garbage collector
Java的堆是一个运行时数据区,类的实例从中分配空间,堆中存储着正在运行的应用程序建立的所有对象。垃圾回收是一种动态存储管理技术,它自动释放不再被程序引用的对象,按照特定的垃圾收集算法来实现资源的自动回收。一般来说,堆的回收是由垃圾收集器负责的,尽管JVM规范并不要求特殊的垃圾回收技术,但是由于内存的有限性,JVM在实现的时候都有一个由垃圾回收所管理的堆。
一、垃圾回收及其意义
正在运行的程序中被引用的对象处于存活状态,不再被引用的对象就是通常所说的垃圾,查找并释放垃圾对象所占用内存空间的过程称为垃圾收集。
在Java中,当没有对象引用指向分配给某个对象的内存时,该内存便成为垃圾。JVM的一个系统级线程会自动释放该内存。除了释放没有用的对象,垃圾收集也可以清除内存记录碎片。由于创建对象和释放对象所占的内存空间,内存会出现碎片。碎片整理将所占用的堆内存移到堆的一端,将整理出的内存分配给新的对象。
垃圾收集机制有如下优点:首先,它能使编程效率提高。在没有垃圾收集机制的时候,可能要花许多时间来解决一个难懂的存储器问题,而使用Java的垃圾收集机制可大大节省时间。其次,它能避免内存渗漏体的产生,保护程序的完整性, 垃圾收集是Java语言安全性策略的一个重要组成部分。
垃圾收集的一个潜在的缺点是它的开销影响程序性能。Java虚拟机必须追踪运行程序中有用的对象,并且释放没用的对象。这一个过程需要花费处理器的时间。其次垃圾收集算法的不完备性,许多垃圾收集算法不能保证100%收集到所有的废弃内存。
二、垃圾的判断标准与回收方法
垃圾收集器判断一个对象的内存空间是否无用的标准是:如果该对象不能再被程序中任何一个“活动的部分”所引用,此时我们说,该对象的内存空间已经无用。所谓“活动的部分”,是指程序中某部分参与程序的调用,尚未执行完毕。
常见的一种情况是,当内存中的一个对象不再被任何变量引用的时候,这个对象就成为内存中的垃圾。Java的垃圾收集机制可以发现这种没有任何引用的对象,并在适当时候回收该对象所使用的内存。例如:
Integer i = new Integer(0);
...
i = null;// 此时,前面Integer(0)所产生的对象就成为垃圾。
具体的说,一个变量或对象是否垃圾可遵循如下规则进行判断:
(一)变量出了作用域就成为垃圾。
(二)变量名失去指向就会变成垃圾。
(三)对象失去变量名的指向同样变成垃圾。
(四)匿名对象本身就是垃圾。
垃圾收集在多数情况下是自动进行的,也可使用System.gc()方法提醒jvm检查有没有要回收的对象,它不明确的指定jvm去回收哪个对象。垃圾收集是JVM上优先级最低的线程,调用System.gc()在多数时候并不马上进行垃圾收集。
项目中最好能手动释放资源,jdk源码里流的部分的close()方法,其实底层都是手动释放:
if (inputStream != null)
{
inputStream.invalidate();
inputStream = null;
}
在对性能要求比较高的项目中,如果一个对象用完后要将其引用变量指向null。
三、Java垃圾收集工作的的特点
经过前面的分析,可以发现Java的垃圾回收有以下特点:
(一)垃圾收集线程作为低优先级的线程运行,但在系统可用内存量过低的时候,可能会突发地执行来释放内存资源。垃圾收集器不可以被强制执行,但程序员可以通过调用System.gc()方法来建议执行垃圾收集器。
(二)不能保证一个无用的对象一定会被垃圾收集器收集,也不能保证垃圾收集器在一段Java代码中一定会执行,因此在程序执行过程中被分配出去的内存空间可能会一直保留到该程序执行完毕。由此可见,彻底地根绝内存渗漏体的产生也是不可能的。
(三)可以通过将对象的引用变量置为null来通知垃圾收集器来收集该对象。但如果该对象连接有事件监听器,那它还是不能被收集。所以在将引用变量置为null之前,应首先除去监听器。
(四)每一个对象都有一个finalize()方法,这个方法是从Object类继承的。finalize()方法用来回收内存以外的系统资源,书写程序时该方法的顺序和方法的实际调用顺序是不相干的,这是finalize( )方法的特点。
Java语言允许程序员为任何对象添加finalize()方法,该方法会在垃圾收集器回收对象之前被调用。但不要过分依赖该方法对系统资源的回收,因为该方法调用后的执行结果是不可预知的。
(五)当一个方法执行完毕,其中的局部变量就会超出使用范围,此时可以被当作垃圾收集,以后再调用该方法时,其中的局部变量便会被重新创建。
结束语:
对于Java的垃圾回收工作,在写程序时要考虑以下准则:
(一)不要试图去假定垃圾收集发生的时间,这一切都是未知的。
(二)Java提供了一些用于垃圾收集的类,而且提供了建议进行垃圾收集的方法——System.gc(),但这是一个不确定的方法。Java并不保证每次调用该方法就一定能够启动垃圾收集。
(三)挑选适合自己的垃圾收集器。如果系统没有特殊和苛刻的性能要求,可以采用JVM的缺省选项。否则可以考虑使用有针对性的垃圾收集器,例如增量收集器适合实时性要求高的系统。具有较高的配置,有较多闲置资源的系统可以考虑使用并行标记/清除收集器。
(四)应尽早释放无用对象。引用变量在退出活动域后要置为null,通知垃圾收集器来收集该对象,还要注意引用的对象是否被监听,如果有,要先去掉监听器。
Java开发人员可以不重视JVM中堆内存的分配和垃圾收集,但是充分理解Java的这一特性可以让我们更有效地利用资源。
参考文献:
[1]http://java.ociweb.com/mark/other-presentations/JavaGC.pdf
[2]http://www.artima.com/insidejvm/ed2/gcP.html
[3]http://en.wikipedia.org/wiki/Garbage_collection_(computer_science)
[4]http://www.petefreitag.com/articles/gctuning/
作者简介:徐小龙(1977-),男,山东潍坊人,硕士,讲师,主要研究方向:网络通信,网络编程,单位:曲阜师范大学计算机科学学院。
关键词:Java虚拟机;垃圾收集;垃圾收集器
中图分类号:TP311.1 文献标识码:A文章编号:1007-9599 (2011) 01-0000-01
Comprehensive Analysis of Java Garbage Collection Mechanism
Xu Xiaolong
(Institute of Computer Science,Qufu Normal University,Rizhao276826,China)
Abstract:Garbage collection is a java language feature which is different from other programming languages.But most current Java books relevant garbage collection content almost no or do only very simple introduction.This paper analyzes the java garbage collection mechanism from several aspects.Learners can generates a comprehensive understanding of the mechanism.
Keywords:JVM;Garbage collection;Garbage collector
Java的堆是一个运行时数据区,类的实例从中分配空间,堆中存储着正在运行的应用程序建立的所有对象。垃圾回收是一种动态存储管理技术,它自动释放不再被程序引用的对象,按照特定的垃圾收集算法来实现资源的自动回收。一般来说,堆的回收是由垃圾收集器负责的,尽管JVM规范并不要求特殊的垃圾回收技术,但是由于内存的有限性,JVM在实现的时候都有一个由垃圾回收所管理的堆。
一、垃圾回收及其意义
正在运行的程序中被引用的对象处于存活状态,不再被引用的对象就是通常所说的垃圾,查找并释放垃圾对象所占用内存空间的过程称为垃圾收集。
在Java中,当没有对象引用指向分配给某个对象的内存时,该内存便成为垃圾。JVM的一个系统级线程会自动释放该内存。除了释放没有用的对象,垃圾收集也可以清除内存记录碎片。由于创建对象和释放对象所占的内存空间,内存会出现碎片。碎片整理将所占用的堆内存移到堆的一端,将整理出的内存分配给新的对象。
垃圾收集机制有如下优点:首先,它能使编程效率提高。在没有垃圾收集机制的时候,可能要花许多时间来解决一个难懂的存储器问题,而使用Java的垃圾收集机制可大大节省时间。其次,它能避免内存渗漏体的产生,保护程序的完整性, 垃圾收集是Java语言安全性策略的一个重要组成部分。
垃圾收集的一个潜在的缺点是它的开销影响程序性能。Java虚拟机必须追踪运行程序中有用的对象,并且释放没用的对象。这一个过程需要花费处理器的时间。其次垃圾收集算法的不完备性,许多垃圾收集算法不能保证100%收集到所有的废弃内存。
二、垃圾的判断标准与回收方法
垃圾收集器判断一个对象的内存空间是否无用的标准是:如果该对象不能再被程序中任何一个“活动的部分”所引用,此时我们说,该对象的内存空间已经无用。所谓“活动的部分”,是指程序中某部分参与程序的调用,尚未执行完毕。
常见的一种情况是,当内存中的一个对象不再被任何变量引用的时候,这个对象就成为内存中的垃圾。Java的垃圾收集机制可以发现这种没有任何引用的对象,并在适当时候回收该对象所使用的内存。例如:
Integer i = new Integer(0);
...
i = null;// 此时,前面Integer(0)所产生的对象就成为垃圾。
具体的说,一个变量或对象是否垃圾可遵循如下规则进行判断:
(一)变量出了作用域就成为垃圾。
(二)变量名失去指向就会变成垃圾。
(三)对象失去变量名的指向同样变成垃圾。
(四)匿名对象本身就是垃圾。
垃圾收集在多数情况下是自动进行的,也可使用System.gc()方法提醒jvm检查有没有要回收的对象,它不明确的指定jvm去回收哪个对象。垃圾收集是JVM上优先级最低的线程,调用System.gc()在多数时候并不马上进行垃圾收集。
项目中最好能手动释放资源,jdk源码里流的部分的close()方法,其实底层都是手动释放:
if (inputStream != null)
{
inputStream.invalidate();
inputStream = null;
}
在对性能要求比较高的项目中,如果一个对象用完后要将其引用变量指向null。
三、Java垃圾收集工作的的特点
经过前面的分析,可以发现Java的垃圾回收有以下特点:
(一)垃圾收集线程作为低优先级的线程运行,但在系统可用内存量过低的时候,可能会突发地执行来释放内存资源。垃圾收集器不可以被强制执行,但程序员可以通过调用System.gc()方法来建议执行垃圾收集器。
(二)不能保证一个无用的对象一定会被垃圾收集器收集,也不能保证垃圾收集器在一段Java代码中一定会执行,因此在程序执行过程中被分配出去的内存空间可能会一直保留到该程序执行完毕。由此可见,彻底地根绝内存渗漏体的产生也是不可能的。
(三)可以通过将对象的引用变量置为null来通知垃圾收集器来收集该对象。但如果该对象连接有事件监听器,那它还是不能被收集。所以在将引用变量置为null之前,应首先除去监听器。
(四)每一个对象都有一个finalize()方法,这个方法是从Object类继承的。finalize()方法用来回收内存以外的系统资源,书写程序时该方法的顺序和方法的实际调用顺序是不相干的,这是finalize( )方法的特点。
Java语言允许程序员为任何对象添加finalize()方法,该方法会在垃圾收集器回收对象之前被调用。但不要过分依赖该方法对系统资源的回收,因为该方法调用后的执行结果是不可预知的。
(五)当一个方法执行完毕,其中的局部变量就会超出使用范围,此时可以被当作垃圾收集,以后再调用该方法时,其中的局部变量便会被重新创建。
结束语:
对于Java的垃圾回收工作,在写程序时要考虑以下准则:
(一)不要试图去假定垃圾收集发生的时间,这一切都是未知的。
(二)Java提供了一些用于垃圾收集的类,而且提供了建议进行垃圾收集的方法——System.gc(),但这是一个不确定的方法。Java并不保证每次调用该方法就一定能够启动垃圾收集。
(三)挑选适合自己的垃圾收集器。如果系统没有特殊和苛刻的性能要求,可以采用JVM的缺省选项。否则可以考虑使用有针对性的垃圾收集器,例如增量收集器适合实时性要求高的系统。具有较高的配置,有较多闲置资源的系统可以考虑使用并行标记/清除收集器。
(四)应尽早释放无用对象。引用变量在退出活动域后要置为null,通知垃圾收集器来收集该对象,还要注意引用的对象是否被监听,如果有,要先去掉监听器。
Java开发人员可以不重视JVM中堆内存的分配和垃圾收集,但是充分理解Java的这一特性可以让我们更有效地利用资源。
参考文献:
[1]http://java.ociweb.com/mark/other-presentations/JavaGC.pdf
[2]http://www.artima.com/insidejvm/ed2/gcP.html
[3]http://en.wikipedia.org/wiki/Garbage_collection_(computer_science)
[4]http://www.petefreitag.com/articles/gctuning/
作者简介:徐小龙(1977-),男,山东潍坊人,硕士,讲师,主要研究方向:网络通信,网络编程,单位:曲阜师范大学计算机科学学院。