本帖最后由 zhangchen91 于 2011-11-09 11:58:28 编辑

解决方案 »

  1.   

    Frame中有事件环,类似于
    while(true)
    之类的构造。
    即便是没有变量引用它,它自己占着CPU呢。
      

  2.   

    内存确实 没有销毁的,而且 还在运行态。并不是指向null了就会销毁,比如我new Thread(xxx).start(),这个没有指向,但可能一直会在运行。销毁对象要具体问题具体分析,比如流,线程等都有提供销毁方法的。基本数据类型或是普通类在不可达情况下会垃圾回收掉(这也只是有可能而已)。
      

  3.   

    垃圾回收不是 你不用了就立即回收如果你想认为回收的话,可手动调用垃圾回收的方法system.gc();但是一般不提倡这么干lz这种情况是还在运行中。。
      

  4.   


    class A {
          public A(){
            B =new B();
            b.obj=this;
           b.start();
           }  static class B extends Thread{
            Object obj;
             public void run(){
                 while(true){
                      //do nothing
                 }
             }
      }
    }
    你new A 类, 看A类会不会回收。
      

  5.   

    每个FRAME都是一个线程在执行,线程在执行完之前,是不会被垃圾回收的。它在等待你的一个触发
      

  6.   

    没有啊。Frame哪怕不被你的程序持有,也会被系统持有,所以是不会被垃圾收集的。楼主可以试试这个代码 for(Frame f : Frame.getFrames()){ //打印系统中持有的Frame。
    System.out.println(f);
    }
      

  7.   


    对于流如果没有显示的调用close(),那么流并不会被关闭,那么当程序结束的时候流的对象有被回收吗?
    这跟我上面提得问题有区别吗?
      

  8.   

    这两个问题虽然有共性,都在讨论和系统资源有关的对象的垃圾回收问题,但是我的建议还是要区别对待。
    得看具体情况的。
    下面的代码你可以试试看,没有调用close方法,但流对象确实被回收了。public class AWT {
    public static void main(String[] args) throws IOException {
    FileInputStream fio = new MyFileInputStream("temp.txt");
    fio.read();
    fio = null; 
    System.gc(); 
    try{
    Thread.sleep(5000);
    }catch(Exception e){}
    }
    }class MyFileInputStream extends FileInputStream{ public MyFileInputStream(String name) throws FileNotFoundException {
    super(name);
    }
    @Override
    protected
    void finalize() {
    try {
    super.finalize();
    } catch (Throwable e) {
    e.printStackTrace();
    }
    System.out.println("fileinputstream gc.");
    }}
      

  9.   

    Frame对象即使没有任何引用也没有被垃圾回收,因为每个Frame都是一个线程在执行,线程在执行完之前是不会被回收的,只有触发Frame的相应事件后,线程结束才会结束。
      

  10.   

    哎,为什么我的java 没有坚持学下去呢,本来都准备花时间去学了,但是又去准备深造了在学校。以至于现在就会点MATLAB了。
      

  11.   

    关于这个问题,有人认为frame对象被回收了,只是窗体的显示是系统资源,所以才会一直存在,你怎么看?
      

  12.   

    测试下,你把窗体对象的引用置空,如果还是响应触发,那就没被回收。
    只是窗体的显示是系统资源,这个我就不知道了,图形不熟,只是针对现象回答的我觉得如果是系统资源显示的话,那JVM退出的时候就不回收了吧,照你的意思,那就是调用System.exit,窗体不会关闭,我记得是会关的
      

  13.   

    frame的问题,2楼的解释和6楼的代码,完全已经把问题说的清清楚楚了!
    我觉得magong在2楼已经解释的非常到位了,而且之后又给了你几段代码。
    楼主还在纠结什么呢?搞不明白,还有这么婆婆妈妈的人!jvm本身只是操作系统的一个普通进程,java代码最终会映射到jvm上去执行,所以在其中创建的任何对象、资源,在java程序运行结束后,都会被操作系统回收,这有什么好怀疑的!
      

  14.   

    好吧,我纠结的是frame显示到底是因为后台线程的引用不符合gc回收原理所以不会回收,还是frame窗体显示属于系统资源所以没有被gc回收?或者说2者都有,从楼上的回答我明白frame至少被后台线程引用,但是这是全部原因吗?假设后台不再引用frame,frame就会消失?
      

  15.   

    嗯,可以肯定的告诉你,线程是全部原因
    frame不属于系统资源,只是调用了系统底层的窗体api而已
      

  16.   

    如果不调用close(),程序结束的时候所有的内存包括系统资源都会被回收,是这样吗?那么关闭流有什么作用?
      

  17.   

    好的,太感谢了,还有,我想问个,对于流,如果不调用close()关掉的话,程序退出也就是jvm退出的时候,所以的内存不都会清空吗,包括gc没有回收的,那么close()也没多大用处啊?
      

  18.   

    close()会自动缓存内数据写入/读入,那么这和flush()功能不是重合了吗?那flush没用?
      

  19.   

    如果不调用close(),操作系统资源是否回收,这要由JVM自己的实现决定。一般依然是可以确保的。
    关闭流是你的应用程序负责任的做法,也可以提前让出系统资源,方便再利用。
      

  20.   

    谢谢啊,我基本弄明白了,还有close调用时会先调用flush吗?那么很多程序在close之前调用flush有什么用啊?
      

  21.   

    谢谢啊,我现在还在上学,接触java不久,本来打算这些问题先搁置的,但是一直憋着不痛快,最近打算买本深入讲解java的书看,出来深入jvm还有什么讲的比较深得书啊?
      

  22.   

    很多地方都说close时它会自己先flush。
    对我来说,我不会依赖于API的副作用。从字面上说,close就是关闭、flush就是强排,在close前调用flush也就是多一行源代码而已,不是错误。
      

  23.   

    大哥,再问个,关于frame是,到底是frame在执行一个线程(类似于new Thread.start() 而线程里使用了while(true)),还是一个进程引用了frame对象?而这个进程是程序并不由frame起得,只是进程里的一个变量引用的frame?不知道有没有听懂我的问题,前者是没有引用指向对象,后者是有引用指向对象
      

  24.   

    两个事情是相关的。
    Frame类上能提供本应用程序创建过的所有frame的清单(无论该frame是否被你自己的变量引用),说明Frame类中引用了这些frame。这是frame不被垃圾收集的主要原因。
    而Frame类持有对这些frame的引用的主要意图,就是为了维护事件环、维护frame和原生window的联系、保持主线程不退出。
      

  25.   

    不知道我有没有听懂你的意思,比如下面这个程序public class Test2 {
    public Test2() {
    run();
    }
    public void run() {
    while(true) {
    System.out.println("helloworld!");
    }
    }
    public static void main(String[] args) {
    new Test2();
    }
    }
    new Test2()并没有定义对像引用它,但是却一直处在运行中,而为了维护这个程序执行下去,实际上程序内存里会有类似于清单的东西引用它。所以所这2个情况是相关的?
      

  26.   

    public class Test2 {
    public Test2() {
    //run();
    }
    public void run() {
    while(true) {
    System.out.println("helloworld!");
    }
    }
    public static void main(String[] args) {
    new Test2().run();
    }
    }
    换成这样呢?
      

  27.   

    很好。当对象的一个方法被调用的时候,JVM会给新开一个栈帧,将对象自己的引用(即this)放入其中。
    也就是说,当run()方法老不结束的时候,对象会被this变量引用,从而造成该对象不会被垃圾收集。