JVM内存直观描述
2017-10-23 本文已影响0人
BK_凌霄
JVM内存简单描述
java的JVM内存可分为3个区:堆(heap),栈(stack)和方法区(method)。
堆
- 存储的都是new出来的对象,每个对象都持有一个对应的class信息;
- JVM只有一个堆,所有线程共享,堆中不放基本数据类型,只放对象本身;
栈
- 每个线程有自己的栈,栈中只保存基本数据类型和对象的引用(具体对象在堆中);
- 栈和栈之间的数据都各自独立、私有,不能访问;
- 栈包含3个部分:基本数据类型区域,执行环境上下文,操作指令区域;
方法区
- 又叫静态区,跟堆一样,被所有线程共享,包含所有加载到内存中的class和static变量;
- 方法区的东西在整个程序中唯一存在;
例子
代码
public class Main {
public static final void main(String[] args) {
Demo demo = new Demo();
demo.print();
}
}
class Demo {
public void print() {
System.out.println("hello");
}
}
从内存角度来看执行过程
- 系统收到我们发出的指令(点击运行后),启动了一个java虚拟机进程,该进程首先从classpath中找到Main.class文件,读取并加载到方法区中(这一过程叫做类加载);
- 解析该类,找到main方法的字节码,准备开始执行;
- 进入main方法,解析第一条语句
Demo demo = new Demo();
发现是需要Demo这个类,然后去方法区查找,由于第一次使用该类,方法区没有找到; - 继续从classpath中查找(如果没有找到,会报ClassNotFoundException的错误),找到Demo后,加载到内存的方法区;
- 下一条指令是new,说明需要在堆内存中新建一份对象(假设新建的对象在内存的0xff10-0xff6f中);
- 下一条指令是赋值符号“=”,要求在当前线程的栈内存中保存下刚才新建的内存对象地址赋值给demo变量(假设demo变量在栈内存中的值为0xff10,指向堆内存中实际的对象);
- 执行demo.print(),首先查找demo对应的实际的对象是否有该方法的字节码(如果没有,会去父类中查找,直到查找失败),查找后执行该方法的字节码包含的方法指令。