目录
并发分配内存的问题
两种解决方法:
- CAS配上失败重试方式保证原子性(默认使用)
- 每个线程在Java堆中预先分配一小块内存,称为本地线程分配缓冲TLAB,如果本地缓冲用完了就需要使用1方法。
可以通过参数设置,-XX:+UseTLAB
,-XX:-UseTLAB
对象的内存布局
实例数据
父类继承的或者自身的都必须记录起来。相同宽度类型的字段会被分配到一起。
存储顺序收到虚拟机配置策略参数和源码顺序影响。
父类定义的变量会排列到子类之前,通过-XX:CompactFields
,默认也为true,将子类较窄的变量插入父类变量的间隙中,以节省一点点的空间。
调整堆大小
-xms20m
-xmx20m
-xmn10m
表示10m分给新生代
调整栈大小
-xss128k
通常不用设置,HotSpot虚拟机选择则不支持运行时动态扩展栈内存,因此,该参数只有在栈容量无法容纳新的栈帧时,或者方法中定了大量局部变量导致的无法容纳新的栈帧,才会导致StackOverflowError异常。
可以编译一个递归方法,用一个变量记录栈深度,调整xss参数设置。
参数设置得过启动时会提示允许的最小值。
调整方法区大小
-XX:MetaspaceSize
-XX:MaxMetaspaceSize
调整元空间大小
新生代大小比例
-XX:SurvivorRatio=8
默认即为8:1:1
打印GC相关信息
JDK9之前使用
查看基本信息-XX:+PrintGC
查看详细详细-XX:+PrintGCDetails
查看GC过程中用户线程停顿时间-XX:+PrintGCApplicationStoppedTime
大对象直接进老年代
-XX:PretenureSizeThreshold
这样做可以避免在Eden区和两个Survivor区之间来回复制,产生大量的内存复制操作。
这个参数只对Serial和ParNew两款收集器有效。
老年代年龄阈值
-XX:MaxTenuringThreshold
必须带上的堆转储快照参数
-XX:HeapDumpOnOutOfMemoryError
表示在堆发生OOM时产出堆转储快照文件
参考:《深入理解Java虚拟机》 第3版 周志明