JVM-内存结构
1. 程序计数器(PC Counter Register)
定义
- 一般是机器的寄存器
作用
- 记录下一条JVM指令指定的地址
特点
- 线程私有
- 不会存在内存溢出
2. 虚拟机栈(JVM Stacks)
定义
- 栈:先进后出的存储结构
- 每个线程运行时所需要的内存空间,成为虚拟机栈
栈帧
- 每个栈由多个栈帧(Frame)组成
- 栈帧对应每个方法运行时需要的内存
- 每个线程只能有一个活动栈帧,对应当前正在执行的那个方法
思考1:垃圾回收是否涉及到栈内存?
答:不涉及。在调用结束后所有栈帧都会被弹出栈(自动出栈),并不需要垃圾回收。
思考2:栈内存的分配越大越好吗?
答:物理内存的大小一定,如果栈的内存分配过大,那么运行线程的数量就会变小。
思考3:方法内的局部变量是否线程安全?
答:如果方法内局部变量是没有逃离方法的作用范围则是安全的;如果局部变量引用了对象,并逃离了方法的作用范围则是不安全的。
栈的内存溢出
原因
- 栈帧过多
- 栈帧过大(不常见)
3. 本地方法栈(Native Method Stacks)
作用
- 为本地方法的运行提供运行空间
4. 堆(Heap)
定义
- Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建
- 通过new关键字创建对象都会使用堆内存
特点
- 线程共享,堆中的对象需要考虑线程安全问题
- 有垃圾回收机制
堆的内存溢出
- 大量对象强引用无法回收导致溢出
特殊情况:垃圾回收后内存占用仍然很高
排查手段:堆转储
5. 方法区(Method Area)
定义
- 方法区与java堆一样,是各个线程共享的内存区域
- 方法区在jvm启动的时候被创建
方法区内存溢出
- 1.8以前是永久代溢出
- 1.8以后是元空间溢出
运行时常量池
- 常量池:一张表。虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等信息
- 运行时常量池:常量池是*.class文件中的,当该类被加载,它的常量池信息就会被放入运行时常量池,并将里面的符号地址改为真实地址。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了