本帖最后由 sillf 于 2010-05-26 15:32:24 编辑

解决方案 »

  1.   

    指针可以存在于栈中或者堆中。
    看下面代码:public class Test {
    public static void main(String[] args) {
    B b = new B();
    }
    }class A{
    int i = 5;
    }class B{
    private A a = new A();
    }对象在堆中,gc就是对堆进行管理的。
    在main方法中,变量b分配于main的方法栈中,jvm可以从栈中的引用开始找到b指向的对象(堆中),它肯定不是垃圾,而这个对象中有个field a(堆中),它指向的对象肯定也不是垃圾,通过有向图跟踪,可以把活对象标记出来。没有标记到的就是死对象了。gc在回收过程中可以对堆进行压缩,虽然会在回收的时候费点事,但可以保证新对象快速分配。一些具体的内容,不同的垃圾回收算法有不同的处理,可以看sun的资料memorymanagement_whitepaper.pdf。
    http://java.sun.com/j2se/reference/whitepapers/memorymanagement_whitepaper.pdf
      

  2.   

    楼上的说明看明白了点点;资料下载了,全英文的,一边翻译一边看还是有些吃力 不大看的明白。我还是有些疑问,如果说存在堆与栈,这个划分是由谁指定的?是操作系统还是内存厂家还是jvm?第二 堆、栈的大小分配是固定的还是动态的?划分依据是什么?第三、最紧要的是对于数据堆的压缩方式我没有看明白,似乎是重新分配存储位置?那么就不能一直运行数据堆的压缩,且在进行压缩的同时不能访问数据,否则就会出错,这样不就会在某个未知时刻中断了程序的运行吗?希望能提供更详细的说明资料  不胜感激!~
      

  3.   

    1、指针的存储位置在哪里?
    引用存放在栈里
    2、实例的存储位置在哪里?
    实例放在内存堆里
    3、jvm如何去查找哪些实例处于可回收状态?
    垃圾回收器会按引用去找实例,遍历所有的引用,把找到的实例复制到另外一块连续的,够
    大的空间,最后没有被复制的就是垃圾,全被回收(这也可以回答第5个问题)
    4、jvm如何确定可回收资源的范围?(根据指针可以确认可回收下界,但可回收上界如何确认?)
    不用确定,因为最后剩下的全是垃圾
    5、如何保证回收后的存储资源是连续的?(如果回收后存储资源不是连续的,那么回收后的存储资源也不一定就是实际可用的,会降低存储资源的使用效率,我想java开发人员还没有到忽略这个问题的地步吧?)
    见第3的答案
    6、对于通过反射创建的实例,为什么不能采用自动回收的机制?而要调用System.gc()强制唤醒回收机制?
    反射创建的实例不用回收吗?没听说过,我如果没记错的话,反向创建实例是调用类的无参
    构造器,应该也会被回收,至于手动调用System.gc(),这个方法不是只有在反射创建对象时
    才被调用,垃圾回收器只有在内存很不够用的情况下才会被调用,很多书上也这么说,垃圾
    回收器什么时候会被调用是不确定的
      

  4.   

    补充一下第4个问题,java使用的内存,在jvm里是有意识的,jvm知道它用的内存是哪些,所以,它对这块内存进行一次垃圾回收的操作,也就是复制到另一个空间里,前面那个空间里就只剩下垃圾
      

  5.   

    在jdk的bin目录下有个工具jvisualvm,打开这个工具,选择一个java程序,通过VisualGC工具可以直观的看堆的情况,比如Perm、Old、Eden等几个区的状况。
      

  6.   

    第一,jvm。可以参考java虚拟机规范,对运行时内存的划分。
    第二,动态的。比如用-Xms等参数可以设置堆内存,用+UseDefaultStackSize参数设置每个线程栈内存。
    第三,有些情况stop-the-world 是无法避免的,可以看具体的gc算法。