JVM的内存模型
JVM内存模型
- JVM内存是由程序计数器、虚拟机栈、本地方法栈、堆内存、永久区(包含常量池)等五大部分组成。
1:程序计数器的目的是为了根据计数器的值来获取下一个要执行的字节码指令,为了保证各个线程之间的计数器互不影响,因此独立存储,所以称为线程私有。
2:当在执行native方法的时候,程序计数器的值则为空,
为什么执行native方法,程序计数器的值要为null?
1: 在程序计数器的定义中,程序计数器存放的是Java字节码的地址,而native方法的方法体是非Java的,所以程序计数器的值才未定义。
那在native方法执行后,线程又如何确保下一次执行的位置?
1: 这是因为每个Java线程都直接映射到一个OS线程上执行。所以native方法就在本地线程上执行,无需理会JVM规范中的程序计数器的概念。仔细看一下JVM规范,如果一个线程执行Native方法,程序计数器的值未定义,可不是一定为空,任何值都可以。native方法执行后会退出(栈帧pop),方法退出返回到被调用的地方继续执行程序。
Tip: OS意思是操作系统(Operating System)的简写。
二:为什么要在jdk1.8之后将方法区去掉?
JDK1.8直接将方法区去掉,在本地内存中新增元数据空间。运行时常量池存放到堆内存中,元数据区存放类加载信息。
- 永久代来存储类信息、常量、静态变量等数据不是个好主意, 很容易遇到内存溢出的问题.JDK8的实现中将类的元数据放入 native memory, 将字符串池和类的静态变量放入java堆中. 可以使用MaxMetaspaceSize对元数据区大小进行调整;
- 对永久代进行调优是很困难的,同时将元空间与堆的垃圾回收进行了隔离,避免永久代引发的Full GC和OOM等问题;
参考文档:周志明的深入理解java虚拟机