内存模型
# 1 内存模型图
# 2 JVM内存参数设置
-Xss设越小count值越小,说明一个线程栈里能分配的栈帧就越少,但对JVM整体来说能开启的线程数会更多。
# 3 为什么要将永久代(PermGen)替换为元空间(MetaSpace)?
1.永久代受限于JVM本身设置的固定大小上限。元空间使用的是直接内存,只受本机可用内存限制。
# 4 JVM内存模型包括哪些数据区域?
主要包括5大块。
1.方法区(元空间),堆都为数据共享区域,有线程安全问题。
2.栈、本地方法栈、程序计数器为独享区域,不存在线程问题。
# 4.1 方法区(元空间)
存储已被虚拟机加载的类信息、常量、静态变量,即编译器编译后的代码等数据。方法区还有一个别名叫Non-Heap(非堆)。
# 4.2 堆
此内存区域的唯一目的就是存放对象实例,几乎所有对象实例以及数组都在这里分配内存。
JDK1.7之后开始默认开启逃逸分析:如果某些方法中的对象没有被返回或者未被外面引用(未逃逸),那么该对象可以在栈上分配内存。
# 4.3 栈
栈也就是Java虚拟机栈,由一个个栈帧组成,每个栈帧拥有:
局部变量表、操作数栈、动态链接、方法出口信息。
局部变量表主要存放编译期可知的各种数据类型(byte、short、int、long、float、double、boolean、char)、对象引用。
每一次方法的调用都会有一个对应的栈帧被压入java栈,方法调用结束后,栈帧弹出。
Java方法有2种返回方式:
1.return语句。
2.抛出异常。
不管哪种返回方式都会导致栈帧弹出。
# 4.4 本地方法栈
和虚拟机栈发挥的作用非常相似,区别是:虚拟机栈执行的是Java方法服务,本地方法栈执行的是Native方法服务。
本地方法执行的时候,在本地方法栈也会创建一个栈帧,用于存放该本地方法的局部变量表、操作数栈、动态链接、出口信息。
本地方法执行完毕后也会出栈并释放内存空间。
# 4.5 程序计数器
每条线程都有独立的程序计数器,各线程之间计数器互不影响。
上次更新: 2022/11/24, 17:59:25