tags:

views:

2334

answers:

3

I was really looking at the differences between pass by value and how Java allocates objects and what java does to put objects on the stack.

Is there anyway to access objects allocated on the heap? What mechanisms does java enforce to guarantee that the right method can access the right data off the heap?

It seems like if you were crafty and maybe even manipulate the java bytecode during runtime, that you might be able to manipulate data off the heap when you aren't supposed to?

+5  A: 

All objects in Java are located on the heap. I'm not quite sure what you mean by "access objects from the heap". The only things stored on the stack are the list of functions which called into the current context and their local variables and parameters. All local variables and parameters are either primitive types or references.

If you allocate an object using new (which is the only way to allocate non-primitive types; yes this includes array types), then the object is allocated on the heap, and a reference to that object is stored on either the stack or the heap, depending on if the reference is stored in a local variable/parameter or as a member of another object.

When passed as parameters to functions, all objects are passed by reference - if the function modifies the parameter, the original object is also modified. Identically, one could also say that the object references are passed by value - if you change a parameter to refer to a new object, it will continue to refer to that object for the duration of the function, but the original object which was passed in will still refer to whatever it referred to before. Primitive types are also passed by value.

Adam Rosenfield
There are other ways to allocate new objects (clone, Class.newInstance(), deserialization), but they do all end up on the heap.
Dave L.
The "one could also say that object references are passed by value" explanation is the only accurate one. Saying that objects are passed by reference is inaccurate. Basically Java only has pass-by-value, like C.
Jon Skeet
+8  A: 

There is no instruction in the JVM instruction set that gives arbitrary access to the heap. Hence, bytecode manipulation will not help you here.

The JVM also has a verifier. It checks the code of every method (as a class is being loaded) to verify that the method does not try to pop more values off the execution stack than what it had pushed onto it. This ensures that a method cannot "see" the objects pointed by its calling method.

Finally, local variables are stored in a per-method array (known as the "local variables array"). Again, the verifier makes sure that every read/write instruction from-/to- that array specifies an index that is less than the size of the array. Note that these JVM instructions can only specify a constant index. They cannot take a computed value and use it as an index.

So to recap, the answer is No.

Itay
+2  A: 

Regarding objects on the stack, it is only the new Java 6 VM from SUN (and perhaps some others) that will try to optimize byte code by putting objects on the stack. Typically, all objects will go into the heap. For reference, check out: http://www.ibm.com/developerworks/java/library/j-jtp09275.html

Also the JVM spec is at http://java.sun.com/docs/books/jvms/second_edition/html/Overview.doc.html#6348. The JVM protects its heap by simply not giving you instructions needed to corrupt it. Flaws in JVM implementations may cause your mileage to vary.

I disagree with the Java 6 comments. The new feature of escape analysis potentially allows the JVM to avoid the creation of objects. So the primitive components of what would have been the object (int, float, references, etc) end up on the stack.Objects only exist in the heap. Period.
John M
Another IBM page, http://www.ibm.com/developerworks/library/j-jtp01274.html, disagrees with you John M. It seems that Java can indeed allocate objects on the stack.
Steven Schlansker