概念
对那些作用于不会逃逸出方法的对象, 在分配内存时, 不在将对象分配在堆内存中, 而是将对象属性打散后分配在线程私有栈内存上, 这样随着方法调用结束, 栈上分配打散的对象也被回收掉, 不在增加 GC 额外压力.
Java 对象分配流程
示例
循环创建 1000000000 一个对象, 阻止栈上分配
栈上分配条件: 开启逃逸分析 & 开启标量替换
JVM 参数:
弃用逃逸分析 (不允许判断对象是否可以逃逸出函数体)
-server -Xmx10m -Xms10m -XX:-DoEscapeAnalysis -XX:+PrintGC
使用 server 模式弃用逃逸分析 (-server -XX:-DoEscapeAnalysis), 设置堆空间大小 10m, 初始空间 10m, 打印 GC 日志
弃用标量替换 (不允许对象打散分配到栈上)
-server -Xmx10m -Xms10m -XX:+PrintGC -XX:-EliminateAllocations
以上二选一
代码:
- package com.mousycoder.mycode.happy_jvm;
- /**
- * @version 1.0
- * @author: mousycoder
- * @date: 2019-06-11 16:55
- */
- public class OnStackTest {
- public static class User{
- public int id = 0;
- public String name = "";
- }
- public static void alloc(){
- User u = new User();
- u.id = 5;
- u.name = "mousycoder";
- }
- public static void main(String[] args) {
- long b = System.currentTimeMillis();
- for (int i = 0; i <1000000000; i++) {
- alloc();
- }
- long e = System.currentTimeMillis();
- System.out.println(e-b);
- }
- }
输出:
- [GC (Allocation Failure) 7651K->5603K(9728K), 0.0003680 secs]
- [GC (Allocation Failure) 7651K->5603K(9728K), 0.0003829 secs]
- [GC (Allocation Failure) 7651K->5603K(9728K), 0.0003809 secs]
- [GC (Allocation Failure) 7651K->5603K(9728K), 0.0003731 secs]
- [GC (Allocation Failure) 7651K->5603K(9728K), 0.0003286 secs]
- VisualGC:
分析:
本次发生的是 Minor GC, 发生 GC 的原因是堆空间没有合适的区域能够存放数据结构导致的, 堆从 7651K 回收到 5603K,
来源: http://www.bubuko.com/infodetail-3119930.html