java | JVM内存结构
1.程序计数器
-
定义:记住下一条JVM指令执行的地址
-
特点
-
线程是私有的,每个线程有一个单独的程序计数器
-
不会存在内存溢出
-
2.虚拟机栈
-
1 定义(Java Virtual Machine Stacks)
-
每个线程运行时所需要的内存,每个线程有一个单独的栈,称为虚拟机栈
-
每个栈里面包含多个栈帧,栈帧里装着调用单个方法时方法内的信息(变量等) 递归时每递归一层就会产生一个栈帧,存放相应信息
-
每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法
-
-
2 问题思考
-
垃圾回收不涉及栈内存,因为栈帧用完后会自动出栈销毁,不需要进行回收
-
栈的内存空间分配不是越大越好,内存空间固定,单个栈的内存空间越大,所能划分的栈的个数就越少
-
方法内的局部变量是线程安全的
-
什么是线程安全
在方法内定义一个局部变量,对该局部变量进行操作,且没有返回值,是线程安全的
public static void m1() {
StringBuilder sb = new StringBuilder();
sb.append(1);
sb.append(2);
sb.append(3);
System.out.println(sb.toString());
}在方法内部定义一个局部变量,对改局部变量进行操作,操作后进行返回,是线程不安全的
public static StringBuilder m3() {
StringBuilder sb = new StringBuilder();
sb.append(1);
sb.append(2);
sb.append(3);
return sb;对一个传入的参数进行操作,
public static void m2(StringBuilder sb) {
sb.append(1);
sb.append(2);
sb.append(3);
System.out.println(sb.toString());
}定义一个静态量,两个方法都对这个量进行操作,是线程不安全的
-
总结:如果方法内局部变量没有逃离方法的作用访问,他是线程安全的;如果是局部变量引用了对象,并且逃离了方法的作用范围,那么就是线程不安全的
-
-
-
-
3 栈的内存溢出 StackOverflowError
-
栈帧过多导致内存溢出:递归层数过多
-
栈帧过大导致栈内存溢出:一个方法内包含了过多的数据
-
-
4 线程的运行诊断
public static void main(String[] args) throws JsonProcessingException {
//新建一个部门对象
Dept d = new Dept();
//设置部门的名字
d.setName("Market");
//新建一个员工对象
Emp e1 = new Emp();
//设置员工1名字
e1.setName("zhang");
//设置员工部门为d
e1.setDept(d);
Emp e2 = new Emp();
//设置员工2名字
e2.setName("li");
//设置员工部门为d
e2.setDept(d);
//设置部门里有e1,e2两个员工
d.setEmps(Arrays.asList(e1, e2));
//转换java
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writeValueAsString(d));
}在转换对象过程中,{name:"Market",emps:[{name:"zhangsan",dept:{name:{} ,dept{name:{},…}部门添加员工,而员工中又有一个部门对象,部门对象中又有员工,无限循环,造成内存溢出。
3.本地方法栈
和操作系统交互的方法
4.堆 Heap
-
通过new创建关键字,创建的对象都会使用堆内存
-
是线程共享的,堆中的对象都需要考虑线程安全问题(堆是线程不安全的)
-
有垃圾回收机制
5.方法区
-
定义:存的是和类相关的信息,逻辑上是堆的一部分 实际不一定
-
方法区内存溢出(元空间内存溢出:原空间使用的是系统内存)MetaSpace
-
运行时常量池
-
常量池:一张表,虚拟机指令根据这张表找到要执行的类名、方法名、参数信息等等
-
运行时常量池:常量池是.class文件中的,当该类被加载,它的常量池信息就会被放入运行时常量池,并把里面的符号变成实际内存地址
-
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了