gpt4 book ai didi

java - Java中,哪些对象放在栈上,哪些放在堆上?

转载 作者:搜寻专家 更新时间:2023-11-01 02:30:33 25 4
gpt4 key购买 nike

对于 Java 函数中的语句:

Xxx xxx = new Xxx() {
public Abc abc(final Writer out) {
return new SomeFunction(out) {
boolean isDone = false;
public void start(final String name) {
/* blah blah blah */
}
};
}
};

哪些变量(包括函数)放在堆上,哪些将放在堆栈上?

我问这个问题的原因是 JVM 中的段错误:

kernel: java[14209]: segfault at 00002aab04685ff8 rip 00002aaab308e4d0 rsp 00002aab04685ff0 error 6

00002aab04685ff800002aab04685ff0 很近,看来栈增长太快了。我尝试调查这部分代码,怀疑是否是多次调用该函数时出现问题的原因。有没有可能是堆上的一些变量引用了栈没有清空?

最佳答案

关于特定对象是否进入堆的问题有点牵扯。

一般来说,在Java中,所有的对象都分配在堆上,因为一个方法可能会返回或存储一个指向对象的指针。如果该对象已被放入堆栈,则下次将堆栈帧放在那里时它会被覆盖。

但是,HotSpot JIT 编译器会做一些叫做 Escape Analysis 的事情.该分析通过查看方法的代码来查明对象是否“脱离”了方法的范围。如果一个对象没有转义,编译器可以安全地将它分配到堆栈上。

维基百科有一些关于 Escape Analysis in Java 的更多信息,也关于多线程和锁定。


关于堆栈溢出:调用堆栈上的堆栈帧总是在方法完成后被删除。实际上,甚至不需要明确删除它。下一帧将覆盖之前的内容。

此外,尽管在其他语言(如 C)中,将非常大的对象放入堆栈可能会导致堆栈溢出,但我认为这不会在 Java 中发生。我希望 Sun(Oracle)的工程师足够聪明,不会让 VM 在堆栈上存储巨大的对象。

所以出现栈溢出的唯一可能是嵌套方法调用过多。由于堆栈空间足够大,可以处理任何“正常”方法调用嵌套,因此堆栈溢出通常表示代码中存在无限(或非常大的)递归。

关于java - Java中,哪些对象放在栈上,哪些放在堆上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10481528/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com