A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 贾成龙 中级黑马   /  2012-8-23 01:17  /  2178 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

垃圾回收器的基本原理是什么?垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收?

4 个回复

倒序浏览
对于GC来说,当程序员创建对象时,GC就开始监控这个对象的地址、大小以及使用情况。通常,GC采用有向图的方式记录和管理堆(heap)中的所有对象。通过这种方式确定哪些对象是"可达的",哪些对象是"不可达的"。当GC确定一些对象为"不可达"时,GC就有责任回收这些内存空间。可以。程序员可以手动执行System.gc(),通知GC运行,但是Java语言规范并不保证GC一定会执行。垃圾回收是任何程序员都无法自己控制的,也就是说即使调用了System.gc(),也只是通知虚拟机要回收垃圾,至于虚拟机什么时候运行回收器就不知道了。

回复 使用道具 举报
如果一些分配出去的内存空间不能有效的回收,就会引起系统运行速度的下降,甚至系统瘫痪,这种情况会造成内存泄漏。最直接的感受就是一个软件尤其是大型的软件打开的时间久了,就会感觉电脑非常卡,甚至死机,这就是由于内存使用过高造成的。

在传统的语言如C/C++中,需要程序员手动对内存进行回收,但是因为是人为操作,而且并不一定每次都能准确的进行回收,有可能该回收的没有回收,不该回收的却回收掉,都会对系统造成严重的后果。与之不同的是JAVA语言中,内存的回收不需要程序员手动控制,一切都是由JRE自动进行。JRE会自动负责回收不再使用的内存,这种方式叫做垃圾回收机制。

JAVA中的垃圾回收机制的优点
1、垃圾回收机制可以自动的回收内存中的垃圾,相比于传统的方式,节省了大量的时间和精力,大大提高了编程的效率
2、垃圾回收机制可以有效的提高程序的完整性

垃圾回收机制的特点
1、垃圾回收机制主要针对的是无用的内存空间,这些内存空间都在堆内存中,垃圾回收只是回收消耗的内存资源,对于物理资源无法回收
2、如果希望垃圾回收机制更快的回收垃圾,可以将对象的引用变量设置为null,这样垃圾回收机制就知道该对象在内存中已称为垃圾,就会自动回收
3、垃圾回收机制有可能定时回收,也有可能是在CPU空闲时回收,也有可能是在内存消耗过多中回收,因此充满了不确定性,不能准确的控制其进行

评分

参与人数 1技术分 +1 收起 理由
张_涛 + 1 赞一个!

查看全部评分

回复 使用道具 举报
垃圾回收一种动态存储管理技术,它自动地释放不再被程序引用的对象,按照特定的垃圾收集算法来实现资源自动回收的功能。
在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾。JVM的一个系统级线程会自动释放该内存块。垃圾收集意味着程序不再需要的对象是"无用信息",这些信息将被丢弃。当一个对象不再被引用的时候,内存回收它占领的空间,以便空间被后来的新对象使用。事实上,除了释放没用的对象,垃圾收集也可以清除内存记录碎片。由于创建对象和垃圾收集器释放丢弃对象所占的内存空间,内存会出现碎片。碎片是分配给对象的内存块之间的空闲内存洞。碎片整理将所占用的堆内存移到堆的一端,JVM将整理出的内存分配给新的对象。
垃圾收集发生的不可预知性:由于实现了不同的垃圾收集算法和采用了不同的收集机制,所以它有可能是定时发生,有可能是当出现系统空闲CPU资源时发生,也有可能是和原始的垃圾收集一样,等到内存消耗出现极限时发生,这与垃圾收集器的选择和具体的设置都有关系

评分

参与人数 1技术分 +1 收起 理由
包晗 + 1

查看全部评分

回复 使用道具 举报
       Java的堆像一个传送带,每分配一个新对象,它就往前移动一格。这意味着对象存储空间的分配速度相当快。
Java的“堆指针”只是简单地移动到尚未分配的领域。也就是说,分配空间的时候,“堆指针”只管依次往前移动
而不管后面的对象是否还要被释放掉。如果可用内存耗尽之前程序就退出,这样的话垃圾回收器压根就不会被激活。      由于“堆指针”只管依次往前移动,总有一天内存会被耗尽,垃圾回收器就开始释放内存。怎么判断某个对象该被回收呢?
当堆栈或静态存储区没有对这个对象的引用时,它就应该被回收了。
    Java有两种方式:
   一种是“停止-复制”:理论上是先暂停程序的运行(所以它不属于后台回收模式),然后将所有存活的对象从当前堆复制到另一个堆,
没有被复制的全是垃圾。当对象被复制到新堆上时,它们是一个挨着一个的,所以新堆保持紧凑排列。然后就可以按前述方法简单、
直接地分配内存了。这将导致大量内存复制行为,内存分配是以较大的“块”为单位的。有了块之后,垃圾回收器就可以不往堆里拷贝对象了,
直接就可以往废弃的块里拷贝对象了。
   另一种是“标记-清扫”:它的思路同样是从堆栈和静态存储区出发,遍历所有的引用,进而找出所有存活的对象。每当它找到一个存活对象,
就会给对象一个标记。这个过程中不会回收任何对象。只有全部标记完成时,没有标记的对象将被释放,不会发生任何复制工作,所以剩下的堆空间是不连续的,
然后垃圾回收器重新整理剩余的对象,使它们是连续排列的。
当垃圾回收器第一次启动时,它执行的是“停止-复制”,因为这个时刻内存有太多的垃圾。然后Java虚拟机会进行监视,如果所有对象都很稳定,
垃圾回收器的效率降低的话,就切换到“标记-清扫”方式;同样,Java虚拟机会跟踪“标记-清扫”效果,要是堆空间出现很多碎片,就会切换到“停止-复制”方式。

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马