0x01.JVM内存划分关系
JVM体系结构(简单版)
运行时数据区的主要作用:
区域名称 | 实际作用 |
---|---|
寄存器 | 保存有当前正在执行的JVM指令的地址。 |
本地方法栈 | 为JVM使用到的Native方法服务 |
方法区 | 存储可执行的.class文件 |
堆内存 | 存储数组或者对象 |
方法栈 | 方法运行时使用的内存 |
本文主要研究运行时数据区中的堆,栈,方法区
0x02.分析一段简单代码,了解数组数组创建过程
- 看一下下面这段代码:
public stativ void main(String args[]){
int[] a=new int[5];
System.out.println(a);
}
- 相信大家很容易知道,输出的内容就是a数组在内存中的地址。
- 那这个地址实际上指的是哪里呢?
- 我们一起分析一下这个程序的运行流程:
仅分析一下主要new出数组的过程,其它的细节此处省略。
堆栈上的主要执行流程:
1.main方法入栈:
2.读取new语句,在堆中开辟空间,存储数据:
-
堆会给数组分配初始值。
-
到这里,我们应该就可以知道,实际的地址是在堆中分配的地址。
0x03.通过堆-栈-方法区,了解对象在内存中存储
- 再来看一段简单的代码:
- 一个People类:
public class Peolple{
String name;
int age;
String sex
public void eat{
System.out.println("吃饭");
}
}
- main方法:
public static void main(String args[]){
Perple people=new People();
people.name="ATFWUS";
people.age=18;
people.sex="man";
people.eat();
}
内存结构分析(单个对象):
0x04.细究堆-栈-方法区在内存中的作用
- 堆和栈的关系用一句话描述就是:栈管运行,堆管存储
1.堆
-
主要:用来存放程序动态生成的数据。
-
重点:堆是内存中共享的区域,要考虑线程安全的问题。
-
凡是
new
出来的对象,都在堆中:- 存储的是成员变量。
- 静态变量存储在方法区。
- 而成员变量的值存储在常量池中。
- 成员方法存储在方法区中,是此类所有实现实例共享的。
-
常量池:
- 常量池在堆中。
- JVM为每一个加载的类维护一个常量池。
- 用于存储成员变量中的数值。
2.栈
-
栈是线程独享的。每一个线程都有自己的线程栈。
-
栈的生命周期跟随线程的生命周期。
-
栈存储的数据:(栈帧)
- ① 本地变量 : 参数,返回值,方法内的变量;
- ② 栈操作 : 栈指针(ebp,esp);
- ③ 栈帧数据 : 类文件、方法等。
-
栈是方法运行时使用的内存。
3.方法区
-
供各线程 共享 的运行时内存区域。
-
存储了每一个类的结构信息。
-
方法区主要用于存储已经被虚拟机加载的类的信息、常量、静态变量等。
- 在JVM加载某个类时,会抽取出对应.class文件中类相关的信息并以特定结构存到方法区中,当程序运行时,JVM则会到方法区中去查找使用对应类信息。