黑马程序员技术交流社区

标题: Java垃圾回收 [打印本页]

作者: 蒋先    时间: 2011-10-12 11:25
标题: Java垃圾回收
Java垃圾回收的优点.
作者: 宁超    时间: 2011-10-12 11:35
Java的垃圾回收机制是的程序员不用担心内存空间的分配,减少了内存溢出.但同时也牺牲了一定的性能.

作者: 庞金梁    时间: 2011-10-12 13:16
JAVA中的对象是在堆上分配,而在堆上分配存储空间的方式是昂贵的.正是由于GC才使java在堆上的空间分配速度得以于其他语言在堆栈上分配速度相媲美.java对象也不再有作用域的概念.作用域是对于引用而言的.垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清楚和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收.程序可以用System.gc() 或Runtime.getRuntime().gc()    请求垃圾回收,但并不保证立即执行垃圾回收.

GC的工作原理: 引用计数,标记复制

"引用计数"是一种简单但速度很慢的垃圾回收技术.所有对象都有一个引用计数器,当有引用连接时计数器加1,当引用离开作用域时或者被置于NULL时,计数器-1,垃圾回收器会在所以包含对象引用的列表上进行遍历,当发现某个对象的引用计数为0时,就释放占用的空间.

"标记复制"的运行机制,垃圾回收器遍历包含所有引用的列表,当发现存活的对象引用时做上标记,这样当遍历完所有对象引用并做上标记的时候,执行垃圾回收,将没有标记的对象堆空间释放.

垃圾回收机制的优点:

Java的垃圾回收机制是的程序员不用担心内存空间的分配,减少了内存溢出.但同时也牺牲了一定的性能.

作者: 敖东    时间: 2011-10-12 13:26
网站上面可以可以下载一个关于面试的WORD文档,上面有个关于垃圾回收的

楼主可以下载下来看看
作者: zhangxinxin    时间: 2011-10-12 13:46
本帖最后由 zhangxinxin 于 2011-10-12 13:52 编辑

简单来说,程序员无需要手动的去消空程序产生的垃圾,java会帮你做。
但java的垃圾回收机制是不定时的,即垃圾产生后,可能不会马上被立刻消除。

作者: 张洋铭    时间: 2011-10-12 14:56
1. 在C++中,堆内存里的数据是不会自动释放的,也就是说,即使没有对该数据的引用,它也存放在内存里占个地方,想要解决,就需要程序员手动写代码释放,如果程序员忘写了,那就悲催喽。试想如果程序运行一天,在内存中存放的无用数据得有多少,越是大型程序越明显。到最后因为内存放不下了导致死机,崩溃~~~

2. Java为了防止这种现象的产生,就采用了垃圾回收机制。也就是说,当堆内存的数据没有引用时,就是垃圾数据,会被自动释放掉。这点也就是大家总说java简单的一个最明显的体现,程序员基本不用关注内存问题。
作者: 朱华    时间: 2011-10-13 11:41
纯手打,请区分。垃圾回收器对于JAVA开发者来说几乎是摸不到的东西,他的优点是让你省去了自己管理内存空间的麻烦。
比如说一个由C编写的信息管理的应用程序,其中有一个含有隐患的方法,它每次执行都会导致在内存中开辟了一块区域,但是这块区域一直都没有被释放,每次运行都会多一块新区域,由于服务器长时间的运行,即便是再小的一块内存,时间久了积攒多了就会导致服务器死机,而这对于BS架构的WEB项目也是同理的。
C程序员们针对这种情况,写程序的时候必须要自己处理内存的释放,就好像张老师常说的一个习惯,inputstream,outputstream,用完了以后,别忘了关门一样。
JAVA语言针对这种情况,提供了一个名叫垃圾回收器的东西,如果你的程序在运行过程中存在那种在内存空间中占据着资源,但是又不会有其他对象访问到它,那么它就会变成内存中的一块“孤岛”,那么垃圾回收器就会去回收这块“孤岛”,释放它所占用的内存空间,所以JAVA程序员就不用自己去处理这种情况,而可以专心于业务代码。
垃圾回收器带来便利的同时,我感觉也带来了隐患,因为这反倒让大量的JAVA开发者不善于管理自己的内存,并且凡是出现的内存问题都相应的变得难以察觉,导致开发者遇到内存相关的问题时会无措。
作者: 刘小峰    时间: 2011-12-27 22:26
Java堆的管理—垃圾回收提到一下几点,很不错,或许可以作为写程序时候的准则:
(1)不要试图去假定垃圾收集发生的时间,这一切都是未知的。比如,方法中的一个临时对象在方法调用完毕后就变成了无用对象,这个时候它的内存就可以被释放。
  (2)Java中提供了一些和垃圾收集打交道的类,而且提供了一种强行执行垃圾收集的方法--调用System.gc(),但这同样是个不确定的方法。Java 中并不保证每次调用该方法就一定能够启动垃圾收集,它只不过会向JVM发出这样一个申请,到底是否真正执行垃圾收集,一切都是个未知数。

  (3)挑选适合自己的垃圾收集器。一般来说,如果系统没有特殊和苛刻的性能要求,可以采用JVM的缺省选项。否则可以考虑使用有针对性的垃圾收集器,比如增量收集器就比较适合实时性要求较高的系统之中。系统具有较高的配置,有比较多的闲置资源,可以考虑使用并行标记/清除收集器。

  (4)关键的也是难把握的问题是内存泄漏。良好的编程习惯和严谨的编程态度永远是最重要的,不要让自己的一个小错误导致内存出现大漏洞。

  (5)尽早释放无用对象的引用。大多数程序员在使用临时变量的时候,都是让引用变量在退出活动域(scope)后,自动设置为null,暗示垃圾收集器来收集该对象,还必须注意该引用的对象是否被监听,如果有,则要去掉监听器,然后再赋空值。

就是说,对于频繁申请内存和释放内存的操作,还是自己控制一下比较好,但是System.gc()的方法不一定适用,最好使用finallize强制执行或者写自己的finallize方法。
作者: 何创    时间: 2012-10-24 16:59
说说垃圾收集的意义

在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象;而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾。JVM的一个系统级线程会自动释放该内存块。垃圾收集意味着程序不再需要的对象是"无用信息",这些信息将被丢弃。当一个对象不再被引用的时候,内存回收它占领的空间,以便空间被后来的新对象使用。事实上,除了释放没用的对象,垃圾收集也可以清除内存记录碎片。由于创建对象和垃圾收集器释放丢弃对象所占的内存空间,内存会出现碎片。碎片是分配给对象的内存块之间的空闲内存洞。碎片整理将所占用的堆内存移到堆的一端,JVM将整理出的内存分配给新的对象。
垃圾收集能自动释放内存空间,减轻编程的负担。这使Java 虚拟机具有一些优点。首先,它能使编程效率提高。在没有垃圾收集机制的时候,可能要花许多时间来解决一个难懂的存储器问题。在用Java语言编程的时候,靠垃圾收集机制可大大缩短时间。其次是它保护程序的完整性, 垃圾收集是Java语言安全性策略的一个重要部份。

垃圾收集的一个潜在的缺点是它的开销影响程序性能。Java虚拟机必须追踪运行程序中有用的对象, 而且最终释放没用的对象。这一个过程需要花费处理器的时间。其次垃圾收集算法的不完备性,早先采用的某些垃圾收集算法就不能保证100%收集到所有的废弃内存。当然随着垃圾收集算法的不断改进以及软硬件运行效率的不断提升,这些问题都可以迎刃而解。






欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2