Java堆&堆

时间:2012-01-10 14:34:49

标签: java stack heap

我想再次学习Java,因为我几年前就离开了。读一本书我在理解Java如何在堆中和堆栈中分配内存时遇到了问题。

这是我所理解的 - 我会尝试用例子来谈论它。

class TestA {
    int a;

    void methodA(int b) {
        a = b;
    }

    int getA() {
        return a;
    }
}

这是一个展示不同情况的示例类。这是我的主要内容:

int b = 3;

TestA obj = new TestA();
obj.methodA(b);
obj.getA();

那会发生什么?


## BEGIN

STACK - 为主要功能

占用一些内存

HEAP - 空


## int b = 3

堆叠 - [为主要功能占用一些内存 - >在这里我们有b]

HEAP - [空]


## TestA obj = new TestA()

堆叠 - [为主要功能占用一些内存 - >这里我们有b和对TestA的引用]

HEAP - [为int获取一些记忆]


## obj.methodA(b);

堆叠 - [为主要功能占用一些内存 - >这里我们有b和对TestA的引用]

HEAP - [为int a取一些内存]和[methodA的另一个内存]


##执行方法A(int b)

堆叠 - [为主要功能占用一些内存 - >这里我们有b和对TestA的引用]和[记忆方法A() - >这里我们在这个函数中使用了b]

HEAP - [为int a取一些内存]和[methodA的另一个内存]


我们有:

  • 堆中的对象和实例字段(原始与否)
  • 堆栈中的函数和范围值

是不是?

3 个答案:

答案 0 :(得分:2)

首先,请记住,堆也将为您的班级(以及其他几个)提供Class个实例。

回复:

  

## TestA obj = new TestA()

     

堆叠 - [为主要功能占用一些内存 - >这里我们有b和对TestA的引用]

     

HEAP - [为int获取一些记忆]

a将在堆中,而不是在堆栈上,作为为TestA实例分配的内存的一部分。 bobj在堆栈上,在进入main时分配(呃,我认为发生这种情况时;可能是JVM没有为它们保留堆栈空间,直到它遇到了程序流中的声明,但是我们正在进入JVM的内部。堆还包含TestA的实例。 (请记住,变量obj与它指向[{1}}]的实例完全不同;每个事物都需要记忆。)

还要记住,堆栈将包含函数调用的返回地址。例如,当TestA调用main时,JVM在methodA返回时应返回的地址也在堆栈中。

还将为异常处理分配各种堆栈结构。

以上主要是理论上的,心灵。欢迎使用JVM进行优化,他们也做了(HotSpot是一个彻底优化的JVM)。例如,@ Voo指出,如果JVM可以检测到它们可以将对象放在堆栈上(例如,当对象实例仅在方法中使用并且JVM的字节码分析表明它不可能存在时)当方法退出时,它是一个杰出的参考。

答案 1 :(得分:1)

尽管Java被指定为堆栈计算机,但实际上并没有以这种方式实现,因此在实际的JVM中,堆栈的大小只会在退出或进入方法时发生变化。

堆永远不会为空 - 它包含Object.class等对象,这些对象在main启动之前由引导类加载器实例化。

new ClassName(...)等所有操作在堆*中分配空间,所有变量声明(int xObject ref)指定在输入封闭函数时应在堆栈上留出空格**。

* - 请参阅有关https://stackoverflow.com/a/8690592/20394的优化的警告 ** - 再次优化可能导致共享堆栈槽。

答案 2 :(得分:0)

默认情况下,所有对象都在堆上分配。但是,有编译器优化允许在堆栈上分配对象(或避免一起分配)。特别是转义分析允许在java 6中使用它。