- Java内存空间(Perm Space、Stack空间、Heap空间)有哪些不同之处?
- JVM在什么时候使用其中一个或另一个?
- 如果我使用Scala/Groovy等语言,是否存在差异?
简单地说:
例如:
Student std = new Student();
执行上述代码后,内存状态将会如下:
push
操作码会将数据存储在堆栈中--它会调整一个寄存器,然后将数据写入指向它的内存位置。这个写入内存的行为在一些汇编语言(如6502)中被称为store。我开始觉得你对“store”这个词有一些特殊的定义。 - Daniel C. Sobraliconst_1
时,您认为会发生什么? - Daniel C. Sobral很抱歉在这么老的问题上添加答案 - 目前的答案不错,但由于静态代码和Java 8更新,它错过了一些边缘情况。
概述
示例代码
public class SimpleVal { //The Class (loaded by a classloader) is in the PermGen
private static final int MAGIC_CONSTANT = 42; //Static fields are stored in PermGen
private static final SimpleVal INSTANCE = new SimpleVal(1); //Static field objects are created in the heap normally, with the reference in the PermGen ('class statics' moved to the heap from Java 7+)
private static SimpleVal previousInstance; //Mutable static fields also have their reference in PermGen so they can easily cause memory leaks
private int value; //Member variables will be part of the heap
public SimpleVal(int realValue) {
value = realValue;
...
}
public static int subtract(SimpleVal val1, SimpleVal val2) {
....
}
public int add(SimpleVal other) { //Only one copy of any method (static or not) exists - in PermGen
int sum = value + other.value; //Local values in methods are placed in the Stack memory
return sum;
}
}
public static void main(String[] args) {
SimpleVal val1 = null;
SimpleVal val2 = new SimpleVal(3); //Both of these variables (references) are stored in the Stack
val1 = new SimpleVal(14); //The actual objects we create and add to the variables are placed in the Heap (app global memory, initially in the Young Gen space and later moved to old generation, unless they are very large they can immediately go old gen)
int prim = val1.add(val2); //primitive value is stored directly in the Stack memory
Integer boxed = new Integer(prim); //but the boxed object will be in the heap (with a reference (variable) in the Stack)
String message = "The output is: "; //In Java 7+ the string is created in the heap, in 6 and below it is created in the PermGen
System.out.println(message + prim);
}
Java 8 Note: PermGen space已被称为Metaspace。它的功能仍然相同,但可以自动调整大小-默认情况下,Metaspace会在本机内存中自动增加其大小,直到达到最大值(在JVM参数中指定),而PermGen始终具有固定的最大大小,与堆内存相邻。
Android Note: 从Android 4.0(实际上从3.0)开始,Android应该遵守所述的内存合同,但在旧版本中,实现出现了问题。在Android-Davlik中,“Stack”内存实际上是基于寄存器的(指令大小和计数在两者之间有所不同,但对开发人员来说功能保持不变)。
最后,有关此主题的更多信息,我在StackOverflow上看到的最好的答案是这里。