- Какви са разликите между пространствата на паметта на Java (Perm Space, Space Stack, Heap Space)?
- Кога JVM използва едно или друго?
- Ако използвам Scala/Groovy/и т.н., има ли разлики?
Купчина срещу стек срещу пермско пространство
Отговори (2)
Просто
- Хийп пространство: Всички живи обекти се разпределят тук.
- Стеково пространство: Съхранява препратки към обекта за променлива в извикване на метод или инстанциране на променлива.
- Perm space: Съхранява информация за заредени класове
Например:
Student std = new Student();
след изпълнение на реда по-горе състоянието на паметта ще бъде такова.
- Купчина: съхранява "new Student()"
- Стек: съхранява информация за "std"
- Perm Space: съхранява информация за ученическия клас
push
на i386 съхранява данни в стека -- той коригира регистър и след това записва данните на позицията в паметта, посочена от него. Самият този акт на запис в паметта се нарича в някои асемблерни езици (като 6502) store. Започвам да си мисля, че имате някакво специално определение за думата магазин.
- person Daniel C. Sobral; 29.07.2011
iconst_1
?
- person Daniel C. Sobral; 29.07.2011
Извинете ме, че добавих отговор към толкова стар въпрос - Текущият отговор е страхотен, но пропуска няколко крайни случая поради статичен код и актуализации на Java 8.
Общ преглед
- Stack
- Allocated per Thread
- Съхранява локални препратки и примитиви
- Това е памет с обхват - Когато метод или нишка приключи, всичките им данни в стека се губят
- Има най-бърз достъп, така че локалният примитив е по-бърз за използване от локалния обект
- Heap
- All allocated object instances exist here
- Разделени на поколения, като най-младото поколение е първото място, където GC изглежда
- Достъпно за всички нишки, така че разпределенията и освобождаванията трябва да бъдат синхронизирани
- Тази памет може да стане фрагментирана (но обикновено не управлявате това сами)
- PermGen
- Stores loaded class information
- Съхранява неизменна информация (примативи, интернирани низове)
- Съхранява статичен клас членове
Примерен код
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: Пространството PermGen беше заменено с това, което се нарича Metaspace. Това все още функционира по същия начин, но може да бъде преоразмерено автоматично - по подразбиране Metaspace автоматично увеличава размера си в основната памет до максимум (посочен в параметрите на JVM), но PermGen винаги има фиксиран максимален размер, съседен на паметта на стека.
Забележка за Android: От Android 4.0 (от 3.0 на практика) Android трябва да спазва описаните договори за памет - но в по-стари версии внедряването беше повредено. Паметта „Stack“ в Android-Davlik всъщност е базирана на регистър (размерите и броят на инструкциите варират между двете, но за разработчика функционалността остава същата).
И накрая, за повече информация най-добрият отговор, който някога съм виждал на тази тема в StackOverflow, е тук