All objects are stored on the heap.

Stack is used for local primitive variables such as ints and doubles. But all objects such as strings, customers or integer objects will be store on the heap.

For the objects on the heap there'll be a pointer to the object which is the variable reference stored on the stack.

Java Memory - The Rules

  • Objects are stored on the heap.
  • Variables are a reference to the object.
  • Local variables are stored on the stack.

Objects are stored physically on the heap. The variable holding the object is just a reference to that object, and the reference if it's held as a local variable will be stored on the stack. Primitives are entirely local variables, there are no objects for these to reference,so these live entirely on the stack.

Java - heap (JVM Memory)_内存分配

age是int类型,存储在stack里。

name是对象(String)的reference,name值存在stack里,对象值存在堆里。

Java - heap (JVM Memory)_sed_02

myList作为对象List的reference,存储在stack里,对象的值存储在堆里。

So when we're in printList the stack will now look like this a new local variable is created called data, and this variable points to the same object as the myList variable, it's a copy of the myList variable and the reference from myList is copied into data.

Because we're now in the printList method, the myList variable is now however out of scope. We can't access it.

Java - heap (JVM Memory)_内存分配_03

data只是一个reference,实际所指向的对象是不变的。

Java - heap (JVM Memory)_内存分配_04

The method was working on a copy of the reference to the list, but not a copy of the actual list object itself.

import java.util.ArrayList;
import java.util.List;

public class Heap {
public static void main(String[] args) {
List<String> myList = new ArrayList<String>();
myList.add("one");
myList.add("two");
myList.add("three");
System.out.println(myList);
printList(myList);
System.out.println(myList);
}

public static void printList(List<String> data) {
String value = data.get(1);
data.add("four");
System.out.println(data);
}
}

运行之后,控制台输出结果:

[one, two, three]
[one, two, three, four]
[one, two, three, four]

reference1 (MyList) 与 reference2 (data) 所指向的对象是同一个,因此最终打印的值也是相同的。

DEMO 2

Java - heap (JVM Memory)_内存分配_05

new 对象的首地址(即第一个元素的地址)是新的,其他元素的地址则是与之前相同。

问题:为什么所有对象都存储在堆中。

答:因为对象需要分配内存,内存分配一般在堆中完成。