运行时数据区
红色表示数据共享空间,灰色是每个线程独有的。
PC寄存器
两个面试常见的问题
如果共享一个PC寄存器,几条线程来回切换,把地址都给覆盖了,那就乱套了。
栈
栈是运行时单位,堆是存储的单位。
1、局部变量表
局部变量表最基本的存储单位是slot槽
slot重复利用
2、操作数栈
3、动态链接
堆
堆空间(年轻代+养老代)大小设置
-X 表示JVM的运行参数。
-Xms:设置初始内存 memory start
-Xmx:设置最大的内存 max
注意:开发中建议将初始堆内存和最大堆内存设置成一样的值。
why?
先初始化一块堆内存,当堆内存不够用的时候向上扩容,等够用又要在进行一个释放,频繁的切换可能会造成系统不必要的压力。
查看设置的参数
方式1、jps
看进程id 再 jstat -gc 进程id
方式2、-XX:+PrintGCDetails
新生区又细分为Eden区和两个Survivor区。两个Survivor的空间只会存一个。
out of memory
年轻代和老年代
-XX:NewRatio
:老年代与新生代的比值,默认是2
-XX:SurvivorRatio
:新生代中Eden区和两个Survivor区的比例是8(8:1:1)
新生代对象分配和回收的过程
有几个问题注意下。
什么时候触发young GC?
Eden满的时候。
那幸存者区满了会触发吗?
不会。幸存者区是伊甸园区满了之后被动的进行回收的。
假如新生代放不下,则要考虑直接放到老年代,要是老年代也放不下,有两种情况。
1、先FGC清理一波,能放下就放下了。
2、对象内存太大了,即使清理了也放不下,直接OOM。
TLAB:Thread Local Alloaction Buffer
占Eden区的1%空间,很小,比如说要new 一个person,他会先考虑放到TLAB,但是如果对象很大或者空间已经放不下了,才会考虑放到Eden里。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qeRuJPBK-1594804735894)(https://upload-images.jianshu.io/upload_images/13173685-f49ca1e8da395337.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]
堆空间常用的参数设置
有这么几个问题。
1、如果Eden区和S1,S2的内存分配时,Eden区特别大,S1,S2很小会怎么样?
2、如果Eden区和S1,S2的内存分配时,Eden区小,S1,S2很大会怎么样?
解:
1、这样只要Eden区往幸存者区放对象,很容易放不下,那么就会被直接送到老年区,而分代的目的是想让对象尽可能在新生代,而这样做分代也就没什么意义了。
2、yong GC的触发条件是Eden区空间不足的时候,这样的话yong GC出现的频率变多,导致用户的整体STW变多,影响整体性能。