【问题标题】:Object is storage and removal from heap memory对象是堆内存中的存储和删除
【发布时间】:2012-06-29 21:43:52
【问题描述】:

谁能向我解释一下对象是如何从 Java 的堆内存中存储和删除的。我正在寻找更多信息,而不仅仅是:

当没有引用时,Object 将被删除

例如:

class Heap
{
    void add(int a, int b)
    {
        System.out.println(a+b);
    }

    public static void main(String ar[])
    {
        Heap obj=new Heap();
        obj.add(4,3);
        obj.add(5,5);
    }
}

obja, `bJ 在 java 内存中是如何分配的。 JVM什么时候会从内存中移除?

【问题讨论】:

  • ab 不在堆上。只有new 创建的东西驻留在堆上。存储和删除操作可能完全取决于 JVM 实现者。
  • garbage collector 不可预测地运行时,对象会从内存中删除。它在内存已满或系统空闲时运行。
  • Java:对象的内存分配 [1]:stackoverflow.com/questions/320980/…

标签: java memory memory-management


【解决方案1】:

简单地说:

  1. obj 是在调用 new Heap() 时在堆上分配的。
  2. ab 都在栈上分配(原始类型,方法参数),内存将在从add 返回时释放。
  3. obj 将在垃圾收集器在执行结束后运行main 后从堆中删除(规范不保证 GC 会在任何给定时间,它会自行确定何时是正确的时间,虽然几乎满堆可能是一个非常常见的触发器)——但在这种情况下,由于程序会终止,它会在从main返回后立即终止。

【讨论】:

  • 是垃圾收集器仅在没有足够的内存或在某些特定的时间间隔内运行
  • 垃圾收集器在运行起来很聪明的时候就会神奇地运行。 (老实说,你应该默认假设 GC 至少和你一样聪明。)
  • @LouisWasserman 是的。尽管人们也应该期望 GC 至少和你一样懒惰。它不是为了减慢你的程序,所以它会尽量避免工作太频繁(“太晚”是 VM 主观的)。
【解决方案2】:

堆对象将在堆内创建。这将包含类和成员变量中的方法。 当您调用一个方法时,该方法将被加载到堆栈中,并在执行该方法后被 jvm 自动丢弃。

堆栈部分内存包含方法、局部变量和引用变量。

部分包含对象(也可能包含引用变量)。

【讨论】:

  • 在这种情况下,对象的引用正在减少。在上面的例子中 a 的第一个值是 4 ,在第二种情况下 a 的值是 5 在堆内存中对象 a 会发生什么
  • 堆对象不会发生任何事情,它将调用堆栈内的方法。因此方法处理将在堆栈内完成,值为 4 和 5。
【解决方案3】:

嗯... a 和 b 根本没有分配在堆上。

它们在堆栈上用于传递给函数。一旦执行离开add(),变量ab 就不能再使用,将被jvm 删除。

【讨论】:

    【解决方案4】:

    当你run your program:

    1. main方法执行之前,JVM会为你分配一个新的执行线程,这个线程(称为主线程)会有一个与之关联的栈,栈是存放局部变量和临时变量的地方数据已放置。
    2. 在堆栈中,一个新框架将与 main 方法相关联。
    3. obj 引用将在主方法堆栈帧中创建。
    4. 当您调用new Heap() 时,JVM 将尝试在堆内存区域中为您的对象分配内存。如果成功,它将为您的局部变量分配一个对象引用,如果失败,它可能会尝试为运行垃圾收集器的对象腾出空间,如果仍然无法为其找到足够的空间,则抛出OutOfMemoryError。李>
    5. 当您在内存引用上调用add(int, int) 方法时,JVM 将首先取消引用该指针以获得对堆中实际对象的访问权,如果失败,将抛出NullPointerException,否则它将寻找要在所谓的方法区(类信息所在的内存区域)中执行的方法。
    6. 如果找到该方法,则在当前执行线程的堆栈中创建一个新帧,并将执行控制权移交给新方法。
    7. 两个变量放置在方法堆栈框架 a 和 b 中,并使用您作为参数传递的值的副本进行初始化(即 4、3)。
    8. 该方法执行其操作,完成后当前堆栈帧被销毁,执行控制权返回到前一帧。
    9. 由于您再次调用方法 add,该过程会重复。
    10. main 方法结束,其堆栈帧被移除。现在obj 引用丢失了,无法再访问堆中的对象。它指向的对象现在无法进行垃圾回收。
    11. JVM 进程终止,所有相关资源都被释放。可能在这种情况下,垃圾回收实际上永远不会运行,但如果运行,堆中的对象占用的内存将被回收。

    【讨论】:

    • 我可以问一件事:当程序终止时,obj 是否会从内存中删除。
    • 你的网站真好。如果照片是你拍的。这真的很明显......太好了
    • @Amith 如果您参考我答案中的链接,该网站不是我的,您参考的信息来自一位名叫 Bill Venners 的作者和《Java 虚拟机内部》一书的出版商,a有点旧但仍然有效。关于您的另一个问题,当JVM进程终止时,操作系统将回收所有资源,因此您在内存中的所有内容都将永远丢失。如果您参考我的照片网站,谢谢 ;-)
    • 老兄,我访问了你的dalorzo.com/portfolio。真的很好,我加入了我的最爱。我非常喜欢。它看起来很新鲜
    猜你喜欢
    • 2019-05-05
    • 1970-01-01
    • 1970-01-01
    • 2013-11-28
    • 1970-01-01
    • 2013-08-21
    • 2021-06-19
    • 2019-08-05
    • 2021-09-08
    相关资源
    最近更新 更多