首页 文章

Java堆和堆栈

提问于
浏览
2

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

堆栈 - 为主要功能占用一些内存

HEAP - 空的


## int b = 3

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

HEAP - [空]


## TestA obj = new TestA()

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

HEAP - [为int a记忆]


## obj.methodA(b);

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

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


## execute methodA(int b)

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

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


我们有:

  • 对象和实例字段(原始与否)在堆中

  • 堆栈中的函数和作用域值

这样对吗?

3 回答

  • 1

    在开始时,请记住堆也将为您的类(以及其他几个)提供 Class 实例 .

    回覆:

    TestA obj = new TestA()STACK - [为主函数占用一些内存 - >这里我们有b和对TestA的引用] HEAP - [为int a取一些内存]

    a 将在堆中,而不是在堆栈上,作为为 TestA 实例分配的内存的一部分 . bobj 在堆栈上,在进入 main 时分配(呃,我认为's when that happens; it could be that the JVM doesn' t为它们保留堆栈空间,直到它遇到程序流中的声明,但是我们进入了JVM的内部) . 堆还包含 TestA 的实例 . (请记住,变量 obj 与它指向[ TestA ]的实例完全不同;每个事物都需要记忆 . )

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

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

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

  • 2

    尽管Java被指定为堆栈计算机,但实际上并没有以这种方式实现,因此在实际的JVM中,堆栈的大小仅在退出或进入方法时才会更改 .

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

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

  • 0

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

相关问题