JVM分为五个部分:
区域划分
1.方法区(Method Area)
2.堆区(Heap)
3.虚拟机栈(VM Stack)
4.本地方法栈(Native Method Stack)
5.程序计数器(Program Counter Register)
总类总结:
1.所有的线程共享堆区和方法区
方法区总结:
- 方法区存放了要加载的类的信息、静态变量、构造函数、final定义的常量和类中的字段和方法;
- 方法区是全局共享的;
- 方法区在可以看做是持久代模型,虽然加载的信息长期保存,但是GC主要针对常量池的回收和已加载类的卸载;
- 方法区中有常量池模型,用于存储编译器生成的常量和引用,一般来说,常量的分配在编译时就能确定,但也不全是,也可以存储在运行时期产生的常量,例如:String类的intern()方法,作用是String类维护了一个常量池,如果调用的字符”hello”已经在常量池中,则直接返回常量池中的地址,否则新建一个常量加入池中,并返回地址。
堆区总结:
- 频繁GC(垃圾回收);
- 主要存储实例对象和数组;
- 堆区由所有线程共享。
虚拟机栈总结:
- 虚拟机栈属于线程私有,每个线程对应一个虚拟机栈,生命周期和线程一样;
- 每个方法被执行时产生一个栈帧(Statck Frame)栈帧用于存储局部变量表、动态链接、操作数和方法出口等信息,当方法被调用时,栈帧入栈,当方法调用结束时,栈帧出栈;
- 局部变量表中存储着方法相关的局部变量,基本数据类型及对象的引用地址,特点是内存空间可以在编译期间就确定,运行时不再改变;
- 两种异常,StackOverFlowError(栈溢出)和OutOfMemoryError(内存溢出)。
本地方法栈总结:
- 执行native方法。
程序计数器总结:
- 在内存中划分,人为无法操作;
- 作用:JVM在解释字节码(.class)文件时,存储当前线程执行的字节码行号,只是一种概念模型。
- 每个程序计数器只能记录一个线程的行号,因此它是线程私有的;
- 如果程序当前正在执行的是一个java方法,则程序计数器记录的是正在执行的虚拟机字节码指令地址,如果执行的是native方法,则计数器的值为空,此内存区是唯一不会抛出OutOfMemoryError的区域。
笔者会不定期更新
参考:
https://blog.csdn.net/anjoyandroid/article/details/78609971