Java堆和堆栈

我想再次学习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();

那么会发生什么?


## 开始

STACK - 为主要功能提供一些内存

HEAP - 空


## int b = 3

STACK - [为主要功能提供一些内存 - >在这里我们有b]

HEAP - [空]


## TestA obj = new TestA()

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

HEAP - [为int a留出一些记忆]


## obj.methodA(b);

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

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


##执行方法A(int b)

STACK - [为主函数获取一些内存 - >这里我们有b和一个对TestA的引用] AND [为methodA() - >获取内存我们在这个函数中使用了b]

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


我们有:

  • 对象和实例字段(原语或不是)在堆中
  • 函数和范围值在堆栈中
  • 这样对吗?


    首先,请记住这个堆还会为您的类(以及其他几个类)提供Class实例。

    回覆:

    ## TestA obj = new TestA()

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

    HEAP - [为int a留出一些记忆]

    a将作为为TestA实例分配的内存的一部分存放在堆中,而不是堆栈中。 bobj在堆栈上,在进入main时进行分配(呃,我认为这是发生的时间;可能是JVM不会为它们保留堆栈空间,直到它遇到程序流程中的声明,但是在那里我们正在进入JVM的内部)。 该堆还包含TestA的实例。 (请记住,变量obj与它指向[ TestA的实例]的内容TestA ;这些东西中的每一个都需要内存。)

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

    各种堆栈结构也将被分配用于异常处理。

    以上主要是理论上的,头脑。 欢迎JVM进行优化,并且它们(HotSpot是彻底优化的JVM)。 例如,@Voo指出,如果JVM可以检测到它们可以将对象放入堆栈,那么它就可以(例如,只在方法中使用对象实例,而JVM的字节码分析表明它不可能存在当该方法退出时,成为它的一个优秀参考)。


    虽然Java被指定为堆栈机器,但实际上并没有以这种方式实际执行,所以在实际的JVM中,堆栈的大小只会在退出或进入方法时发生变化。

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

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

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


    默认情况下,所有对象都分配在堆上。 但是,有编译器优化允许在堆栈上分配对象(或避免一起分配)。 特别是逃逸分析允许在Java 6中这一点。

    链接地址: http://www.djcxy.com/p/255.html

    上一篇: Java heap & stack

    下一篇: Windows assembly heap and stack?