黑马程序员技术交流社区

标题: 求指教:Java有个东西叫垃圾收集器的问题 [打印本页]

作者: 小丑的媳妇2    时间: 2013-3-5 11:20
标题: 求指教:Java有个东西叫垃圾收集器的问题
Java有个东西叫垃圾收集器,它让创建的对象不需要像c/cpp那样delete、free掉,比如大家知道再创建一个对象的时候,会在堆内存开辟一个空间,我想知道的是这个垃圾是怎么回收的,本人是初学者,请高手指教!多谢!
作者: 王亚东    时间: 2013-3-5 14:28
这个垃圾回收机制就像小区的清洁阿姨,不是说有人丢了垃圾她马上就去清扫,而是不定时的清扫,清理完后她就去休息一会,过会再来,如此循环往复。。
也可以手动调用System.gc();立即清理。
作者: 克零岚    时间: 2013-3-5 16:43
本帖最后由 克零岚 于 2013-3-5 16:47 编辑

呵呵,复习了一小下,请看:
  1. (1)所谓“局部内部类”就是在对象的方法成员内部定义的类。而方法中的类,访问同一个方法中的局部变量,却必须要加上一个final。
  2. (2)原因是编译程序实现上的困难:<font color="red">内部类对象的生命周期会超过局部变量的生命期。</font>
  3. 局部变量的生命期:当该方法被调用时,该方法中的局部变量在栈中被创建,当方法调用结束时,退栈,这些局部变量全部死亡。
  4. 内部类对象生命期,与其它类一样,当创建一个局部内部类对象后,只有当没有其它人再引用它时,它才能死亡。
  5. <font color="red">所以完全可能一个方法已调用结束(局部变量已死亡),但该局部类的对象仍然活着。即:局部类的对象生命期会超过局部变量</font>
  6. (3)<font color="red">局部内部类的对象访问同一个方法中的局部变量,那么这就要求只要局部内部类对象还活着,那么栈中的那些它要访问的局部变量就不能“死亡”(否则:它都死了,还访问个什么呢?)。这就是说:局部变量的生命期至少等于或大于局部内部类对象的生命期</font>
  7. (4)解决方法:局部内部类的对象可以访问同一个方法中被定义为final的局部变量。
  8. 定义为final后,编译程序的实现方法:<font color="red">将所有的局部内部类对象要访问的final型局部变量,都拷贝成为该内部类对象中的一个数据成员。这样,即使栈中局部变量(含final)已死亡,但由于它是final,其值永不变,因而局部内部类对象在变量死亡后,照样可以访问final型局部变量</font>
复制代码
清楚了没呀?

作者: scott0610    时间: 2013-3-5 17:02
    Java程序中的内存分配和回收都是由JRE在后台自动进行的。JRE会负责回收那些不再使用的内存,这种机制被称为垃圾回收。通常
JRE会提供一条超级线程来进行检测和控制,一般都是在CPU空闲或者内存不足时自动进行垃圾回收。而程序是无法精确控制垃圾回收的时间和顺序等。
    Java的堆内存是一个运行时数据区,用以保存类的实列(对象),Java虚拟机在堆内存中储存着正在运行的应用程序所建立的所有对象。这些对象不需要程序通过代码来显示的释放。
一般来说,堆内存是由垃圾回收来负责的,所以Java虚拟机在实现都有一个垃圾回收机制管理的堆内存,垃圾回收是一种动态存储管理技术。他自动地释放不在被程序引用的对象,按照特定
的垃圾回收算法来实现内存资源的自动回收功能。
    当一个对象不再被引用的时候,内存回收它所占领的空间,以便空间被后来的新对象使用,事实上,除了释放没用的对象,垃圾回收也可以清除内存记录碎片。
由于创建对象和垃圾回收器释放丢弃对象所占的内存空间,内存会出现碎片。碎片是分配给对象的内存块之间的空闲内存区。碎片整理将所占用的堆内存移到堆的一端。
Java虚拟机整理出的内存分配给新的对象。
作者: 黑马17期-闫东东    时间: 2013-3-7 22:48
本帖最后由 黑马17期-闫东东 于 2013-3-7 22:51 编辑

Java的堆是一个运行时数据区,类的实例(对象)从中分配空间。Java虚拟机(JVM)的堆中储存着正在运行的应用程序所建立的所有对象,这些对象通过new、newarray、anewarray和multianewarray等指令建立,但是它们不需要程序代码来显式地释放。一般来说,堆的是由垃圾回收 来负责的,尽管JVM规范并不要求特殊的垃圾回收技术,甚至根本就不需要垃圾回收,但是由于内存的有限性,JVM在实现的时候都有一个由垃圾回收所管理的堆。垃圾回收是一种动态存储管理技术,它自动地释放不再被程序引用的对象,按照特定的垃圾收集算法来实现资源自动回收的功能。
Java垃圾回收

1、命令行参数透视垃圾收集器的运行

2、使用System.gc()可以不管JVM使用的是哪一种垃圾回收的算法,都可以请求Java的垃圾回收。在命令行中有一个参数-verbosegc可以查看Java使用的堆内存的情况,它的格式如下:

java -verbosegc classfile

可以看个例子:

class TestGC
{
public static void main(String[] args)
{
new TestGC();
System.gc();
System.runFinalization();
}
}


作者: 高梦晓    时间: 2013-3-7 23:32
Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制,Java中的对象不再有“作用域”的概念,只有对象的引用才有“作用域”。垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清楚和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。
回收机制有分代复制垃圾回收和标记垃圾回收,增量垃圾回收。
作者: HM李帅    时间: 2013-3-7 23:43
没记错的话应该是写在jdk底层在程序空闲时间自动调用的

作者: 聂斌    时间: 2013-3-8 00:34
java垃圾回收就是 系统自动把堆内存中没有引用指向的对象定期删除
这个是定期自动调用,一般不用去考虑回收的时间点,另外,如果堆内存中对象比内存多,这时是会报错的。
JAVA垃圾回收机制另一个特点是,进行垃圾回收的线程是一种低优先级的线程,在一个Java程序的生命周期中,它只有在内存空闲的时候才有机会运行。

垃圾回收线程遵循以下两个特性。
1.  自动性。Java技术提供了一个系统级的线程,即垃圾收集器线程,来跟踪每一块分配出去的内存空间,当Java 虚拟机处于空闲循环时,垃圾收集器线程会自动检查每一块分配出去的内存空间,然后自动回收每一块可以回收的无用的内存块。
2.  不可预期性。一个对象成为了垃圾,但是你不能断言,该对象在这行以后就立刻被清除,甚至有可能当程序结束后,该对象仍然占用内存。像Windows这样的软件常常会出现内存不足的情况,JAVA程序很少出现就是因为可以自动回收内存。然而,因为JAVA也不能保证及时地清除无用的对象,所以JAVA程序也会出现内存不足的情况,只是这种情况很少出现。垃圾收集线程在一个Java程序中的执行是自动的,不能强制执行,即使程序员能明确地判断出有一块内存已经无用了,是应该回收的,程序员也不能强制垃圾收集器回收该内存块。程序员唯一能做的就是通过调用System.gc 方法来"建议"执行垃圾收集器,但其是否可以执行,什么时候执行却都是不可知的。

同学以上的观点希望对你有帮助.....




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