按照是否独享、共享分为两类: 每个线程都会独有的区域:栈、程序计数器器、本地方法栈 线程共享区域:堆、方法区 ------>线程安全问题 栈:线程独有的东西 栈帧:栈帧分配空间的方式:每次分出一块来给新的方法栈,即便是递归调用;--> 如果方法一直增加,可能会导致栈溢出 程序计数器:每个线程都有的一块内存空间,存放程序将要运行的内存位置(指针位置); 主要是用于多线程场景下记录程序挂起前的执行位置,便于恢复执行后使用; 动态链接:在程序运行期间,把符号引用转换为对应的代码的内存地址;(静态链接:程序加载的过程中) 方法出口:方法执行完成后要回到main方法中的位置 局部变量表:存放对象在堆中存放的内存位置; 操作数栈:临时存放操作数(变量对应的值)的内存 方法区:常量、静态变量(对象类型存放的还是指针)、类信息; 堆:new出来的对象 年轻代(Eden、Survivor)--三分之一、老年代---三分之二左右; 存储到释放的流程: new出来的对象一般先放到Eden区域,至Eden区域放满之后,JVM调用GC---minor gc 把Eden区域中没有引用的对象回收掉, 假如有引用,会把对象放到Survivor,这是年龄会加1;当年龄增加至15时,会移至老年代区域中.。 当老年代中存满之后会先触发fullgc,fullgc会回收整个对堆和方法区(共享区域),假如无法回收会触发OOM (整个过程可以使用JDK自带的工具-jvisualvm查看;gc流程:minor gc --->full gc) STW:在gc的过程中会触发STW(stop the world)机制,停止用户发起的线程--->页面上显示的就是卡顿; STW的原因:防止在gc的过程中一些对象由非垃圾对象变为垃圾对象 JVM调优主要就是减少full gc,因为她占用的时间比较长,处罚STW的时间也会比较长; springboot 启动参数 设置方法区内、栈等等存大小 -Xss: 栈内存空间值越小,一个线程栈里面可以分配的栈帧就越少; 但是对于JVM来说可以开启的线程数就越多(总的内存资源是有限的,独享区域占用越少,总的数量就会越多);