Разделение памяти JVM
1. Стек**
- приватный поток
- Когда поток выполняет метод, он создает соответствующий кадр стека.
- Фрейм стека, используемый для хранения такой информации, как таблица локальных переменных, стек операндов, динамическая ссылка, выход из метода и т. д.
- Переменные и ссылки, хранящиеся в стеке, являются локальными (т. е. переменные или ссылки, определенные в теле метода), а локальные переменные и ссылки находятся в стеке (включая конечные локальные переменные).
- Локальные переменные восьми базовых типов данных (byte, short, int, long, float, double, char, boolean) (переменные базовых типов данных, определенных в теле метода) хранят соответствующие им значения в стеке
- Если локальная переменная объявлена без явного присвоения, стек не даст присваивания по умолчанию.
- В стеке также хранятся ссылки на локальные объекты (переменные ссылочного типа, определенные в теле метода). Ссылкой на объект является не сам объект, а адрес объекта в куче. Другими словами, ссылка на локальную объект ссылается на Адрес объекта в куче хранится в стеке. Конечно, если ссылка на объект не указывает на конкретный объект, ссылка на объект является нулевой.
Во-вторых, куча**
- обмен потоками
- Все объекты, созданные с помощью ключевого слова new, хранятся в куче Java.
- ! ! ! Переменные экземпляра (нестатические модифицированные переменные-члены) связаны с объектами, поэтому переменные экземпляра также находятся в куче.
- Массивы Java также открывают пространство памяти в куче.
- Механизм сборки мусора Java обрабатывает это автоматически.
3. Область метода**
Метод (область методов) также называется статической областью, в которой хранятся все ① классы, ② статические переменные (статические переменные), ③ статические методы, ④ константы и ⑤ методы-члены.
1. Также известная как статическая область, как и куча, она совместно используется всеми потоками.
2. В области методов хранятся элементы, которые всегда уникальны во всей программе. Вот почему область метода является общей для всех потоков.
-
Константа хранения: переменная-член, измененная static final
-
Хранить статические переменные: статические измененные переменные-члены
- Статические переменные восьми основных типов данных (byte, short, int, long, float, double, char, boolean) откроют место в области метода и сохранят соответствующие значения в области метода метода.
- Для статической переменной ссылочного типа, если ключевое слово new не используется для выделения объекта для статической переменной ссылочного типа (например: static Object obj;), то ссылочный obj объекта будет храниться в методе области, и ей будет присвоено значение по умолчанию null; если, Для статических переменных ссылочного типа, если вы используете новое ключевое слово для размещения объекта в статической переменной ссылочного типа (например: static Person person = new Person ();), ссылка на объект будет храниться в области методов, а сам объект будет храниться в куче. Адрес in также хранится в области методов (обратите внимание, что в это времяСтатические переменные хранят только адрес кучи объекта, а сам объект все еще находится в куче памяти)
-
Методы хранения: статические методы, обычные методы
-
! ! ! В области метода нет переменных экземпляра. Это связано с тем, что загрузка класса предшествует генерации соответствующего объекта класса, а переменные экземпляра связаны с объектом. Нет переменной экземпляра без объекта. Нет объекта, когда класс загружается, поэтому в области методов нет переменных экземпляра, переменные экземпляра хранятся в куче
4. Примеры
public class PersonDemo
{
public static void main(String[] args)
{ //局部变量p和形参args都在main方法的栈帧中
//new Person()对象在堆中分配空间
Person p = new Person();
//sum在栈中,new int[10]在堆中分配空间
int[] sum = new int[10];
}
}
class Person
{ //实例变量name和age在堆(Heap)中分配空间
private String name;
private int age;
//类变量(引用类型)name1和"cn"都在方法区(Method Area)
private static String name1 = "cn";
//类变量(引用类型)name2在方法区(Method Area)
//new String("cn")对象在堆(Heap)中分配空间
private static String name2 = new String("cn");
//num在堆中,new int[10]也在堆中
private int[] num = new int[10];
Person(String name,int age)
{
//this及形参name、age在构造方法被调用时
//会在构造方法的栈帧中开辟空间
this.name = name;
this.age = age;
}
//setName()方法在方法区中
public void setName(String name)
{
this.name = name;
}
//speak()方法在方法区中
public void speak()
{
System.out.println(this.name+"..."+this.age);
}
//showCountry()方法在方法区中
public static void showCountry()
{
System.out.println("country="+country);
}
}
блок-схема
Наконец, с помощью блок-схемы все области связаны вместе.
// AppMain.java
public class AppMain { //运行时,JVM把AppMain的信息都放入方法区
public static void main(String[] args) { //main成员方法本身放入方法区。
Sample test1 = new Sample( " 测试1 " ); //test1是引用,所以放到栈区里,Sample是自定义对象应该放到堆里面
Sample test2 = new Sample( " 测试2 " );
test1.printName();
test2.printName();
}
}
изображение: блок-схема работы JVM
Суммировать:
- Область метода: сохранить шаблон класса
- Куча: содержит экземпляры классов
- стек: выполнить вычисление функции
расширять
- постоянное поколение
Группа разработчиков виртуальной машины HotSpot решила расширить коллекцию поколений GC до области методов или использовать постоянное поколение для реализации области методов. Таким образом, сборщик мусора HotSpot может управлять этой частью, как кучей Java, экономя работу по написанию кода управления памятью для области методов. Для других виртуальных машин (таких как BEA JRockit/IBM J9) не существует концепции постоянной генерации.
- постоянный пул времени выполнения
Пул констант времени выполнениячасть области метода. В дополнение к описательной информации, такой как версия/поле/метод/интерфейс класса, в файле класса также имеется пул констант (таблица пула констант), который используется для хранения различных литералов и символических ссылок, сгенерированных во время компиляции и Эта часть содержимого будет храниться в пуле констант времени выполнения области методов после загрузки класса.
String str1 = "abcd";
String str2 = new String("abcd");
System.out.println(str1==str2);//false
String str1 = "str";
String str2 = "ing";
String str3 = "str" + "ing";
String str4 = str1 + str2;
System.out.println("string" == "str" + "ing");// true
System.out.println(str3 == str4);//false
String str5 = "string";
System.out.println(str3 == str5);//true
объяснять:
- «abcd» — получить объект в пуле констант, а new String («abcd») — создать новый объект непосредственно в пространстве кучи памяти. Всякий раз, когда вы используете новый метод, вам нужно создать новый объект.
- Выражение конкатенации +, только новые объекты, созданные соединением "+" между объектами String, созданными с использованием кавычек для содержания текста, будут добавлены в пул констант.
- Для выражения соединения "+" строковых переменных новые объекты, сгенерированные им, не будут добавляться в пул строк, они принадлежат строкам, созданным во время выполнения, и имеют независимые адреса памяти, поэтому на них не ссылаются из одной и той же строки. объект.
Ссылаться на: