一般问题:Java具有堆和本地堆栈。你可以从堆中访问任何对象吗?

时间:2008-11-14 03:08:11

标签: java jvm stack heap

我真的在看传递值与Java如何分配对象以及java将对象放在堆栈上的方式之间的区别。

无论如何都要访问堆上分配的对象? java强制执行哪些机制来保证正确的方法可以从堆中访问正​​确的数据?

好像你是狡猾的,甚至可能在运行时操作java字节码,你可能能够在不应该的时候从堆中操作数据?

3 个答案:

答案 0 :(得分:17)

JVM指令集中没有任何指令可以对堆进行任意访问。因此,字节码操作对你没有帮助。

JVM还有一个验证程序。它检查每个方法的代码(正在加载一个类),以验证该方法不会尝试从执行堆栈中弹出更多值,而不是它所推送的值。这可以确保方法无法“看到”其调用方法指向的对象。

最后,局部变量存储在每个方法的数组中(称为“局部变量数组”)。同样,验证程序确保从/到该数组的每个读/写指令指定一个小于数组大小的索引。请注意,这些JVM指令只能指定常量索引。他们无法获取计算值并将其用作索引。

回顾一下,答案是否定的。

答案 1 :(得分:9)

Java中的所有对象都位于堆上。我不太清楚“从堆中访问对象”是什么意思。存储在堆栈中的唯一内容是调用当前上下文的函数列表及其局部变量和参数。所有局部变量和参数都是基本类型或引用。

如果使用new分配对象(这是分配非基本类型的唯一方法;是的,这包括数组类型),则在堆上分配对象,并且对该对象的引用是存储在堆栈或堆上,具体取决于引用是存储在本地变量/参数中还是存储在另一个对象的成员中。

当作为参数传递给函数时,所有对象都通过引用传递 - 如果函数修改了参数,则原始对象也会被修改。同样,也可以说对象引用是按值传递的 - 如果更改参数以引用新对象,它将在函数持续时间内继续引用该对象,但是传入的原始对象仍将参考之前提到的任何内容。原始类型也按值传递。

答案 2 :(得分:4)

关于堆栈上的对象,只有来自SUN(可能还有其他一些)的新Java 6 VM会尝试通过将对象放在堆栈上来优化字节代码。通常,所有对象都将进入堆中。如需参考,请查看:http://www.ibm.com/developerworks/java/library/j-jtp09275.html

JVM规范也在http://java.sun.com/docs/books/jvms/second_edition/html/Overview.doc.html#6348。 JVM通过简单地不向您提供破坏它所需的指令来保护其堆。 JVM实施中的缺陷可能会导致您的里程变化。