黑马程序员技术交流社区

标题: 关于垃圾回收的原理? [打印本页]

作者: huima    时间: 2013-4-15 17:11
标题: 关于垃圾回收的原理?
垃圾回收的基本原理是什么?垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收呢?求详细解答。。。
作者: 艾萱    时间: 2013-4-15 17:18
基本原理就是虚拟机每隔一段时间就会运行一次垃圾回收或是在虚拟机认为需要的时候。
主动调用是System.gc()。垃圾回收器运行了当然会收回内在。但悲剧的是,垃圾回收是任何程序员都无法自己控制的,也就是说即使调用了System.gc(),也只是通知虚拟机要回收垃圾,至于虚拟机什么时候运行回收器就不知道了。
作者: 刘永建    时间: 2013-4-15 17:35
Java的垃圾回收机制是Java虚拟机提供的能力,用于在空闲时间以不定时的方式动态回收无任何引用的对象占据的内存空间。
需要注意的是:垃圾回收回收的是无任何引用的对象占据的内存空间而不是对象本身,很多人回答的含义是回收对象,实际上这是不正确的。
System.gc()
Runtime.getRuntime().gc()  
上面的方法调用时用于显式通知JVM可以进行一次垃圾回收,但真正垃圾回收机制具体在什么时间点开始发生动作这同样是不可预料的,这和抢占式的线程在发生作用时的原理一样。
程序员只能通过上面的方法建议JVM回收垃圾,但是JVM是否回收,同样是不可预料的。

作者: Alan    时间: 2013-4-15 18:45
垃圾回收器是Java平台中用的最频繁的一种对象销毁方法。垃圾回收器会全程侦测Java应用程序的运行情况。当发现有些对象成为垃圾时,垃圾回收器就会销毁这些对象,并释放这些对象所占用的内存空间。在这里,程序开发人员需要知道,在哪些情况下垃圾回收器会认为这些对象是垃圾对象。通常情况下,如果发生以下两种情况时,系统会认为这些对象是垃圾对象,需要销毁。    一是将一个NULL值赋值给对象。如用户先建立了一个对象str1。对象用完了之后,再利用赋值语句,将NULL值赋值给这个对象str1,即使用str1=NULL的方式将NULL值赋值给这个对象。此时这个对象与内存中对象的存储地址之间就失去了联系。此时内存中的对象就好像成为了一个无主的对象,就会被垃圾回收器销毁。不过这也有例外。如现在同一个对象有两个名字,分别为str1与str2。此时若只是将NULL值赋值给str1,那么内存的这个对象仍然有一个主人,即str2。此时这个对象还暂时不会被垃圾回收器回收。除非在代码中讲这个对象所关联的所有对象名字都赋值为NULL。此时这个对象才变为无主的对象,才会被垃圾回收器回收。在Java中定义自己的工具库    二是对象其超出了作用范围,这个这个对象就被认为是垃圾对象,被被垃圾回收器回收并释放内存。其实对象跟变量一样,其也有作用域。当超过这个作用域的话,跟变量一样,这个对象也就无效了,其他地方不能够再引用这个对象。此时这个对象就是名存实亡了。为此垃圾回收器也把这种超过作用范围的对象当作垃圾对象来处理。所以说,如果程序员要让对象中的某些成员变量或者成员方法一直有效的话,就需要采用static关键字,让其在变量销毁时仍然有效,或则仍然可以调用这些成员变量与成员方法。
作者: Sword    时间: 2013-4-17 00:29
对于GC来说,当程序员创建对象时,GC就开始监控这个对象的地址、大小以及使用情况。通常,GC采用有向图的方式记录和管理堆(heap)中的所有对象。通过这种方式确定哪些对象是"可达的",哪些对象是"不可达的"。当GC确定一些对象为"不可达"时,GC就有责任回收这些内存空间。可以。程序员可以手动执行System.gc(),通知GC运行,但是Java语言规范并不保证GC一定会执行。强制执行垃圾回收:System.gc()。Runtime.getRuntime().gc()
静态类:static的是属于类的,而不是属于对象的,相当于是全局的,不可能被回收
静态变量本身不会被回收,但是它所引用的对象应该是可以回收的。
gc只回收heap里的对象,对象都是一样的,只要没有对它的引用,就可以被回收(但是不一定被回收). 对象的回收和是否static没有什么关系!
如:static Vector pane = new Vector();  pane = null;  如果没有其它引用的话,原来pane指向的对象实例就会被回收。
Java程序员在编写程序的时候不再需要考虑内存管 理。由于有个垃圾回收机制,Java中的对象不再有"作用域"的概念,只有对象的引用才有"作用域"。垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清楚和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。
垃圾回收器是一个级别很低的线程,它通过不定时监测程序使用的内存中被占用的动态分配的内存内的对象是否还存在它的引用来判断是否该回收那个内存单元,如果不存在则回收,否则相反~~并不是只要监测到就会回收的,因为垃圾回收器线程的低级别,所以当另一个级别比它高的线程跟他同时竞争运行时间时,前者优先运行,我们通过Thread或者继承Runnable的线程都级别都比它高,所以你无法知道垃圾回收器何时回收,System.gc()只是建议垃圾回收器进行回收处理,调用它并不能保证它回立即回收
作者: 陈宇鹏    时间: 2013-4-17 01:46
Java 语言不需要程序员直接控制内存回收,Java程序的内存分配和回收都是由JRE在后台自动进行的。JRE会负责回收那些不再使用的内存,这种机制被称为垃圾回收机制。通常JRE会提供一条超级线程来进行检测和控制,一般都是在CPU空间或内存不足时进行垃圾回收,而程序员无法精确控制垃圾回收的时间和顺序等,

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



--------------------------摘自《疯狂JAVA讲义》
作者: 黄玉昆    时间: 2013-4-17 09:14
如果问题未解决,请继续追问,如果没有问题了,请将帖子分类 改为“已解决”,谢谢




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