JVM逃逸分析之栈上内存分配-例子试验

17 篇文章 0 订阅

说明

1.例子在jdk1.8下示例栈上分配内存的例子;
2.切记一定要run,不能在debug模式下运行!!!

使用代码

package org.example;

public class StackAllocationTest {
    public static void main(String[] args) throws InterruptedException {
        long time = System.currentTimeMillis();
        for (int i = 0; i < 10000000; i++) {
            test();
        }
        System.out.println(String.format("time = %dms", System.currentTimeMillis() - time));
        Thread.sleep(10000000);
    }

    private static void test() {
        // a对象方法内不逃逸,希望能在栈上进行分配空间
        A a = new A();
    }
    static class A {
    }
}

试验1 jstat -gc分析

不启用逃逸分析
jvm参数如下:
-Xmx10m -Xms10m -XX:-DoEscapeAnalysis -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError`
启动程序,然后使用jstat进行分析

D:\YDIdeaWorkspace\java-test>jps
3364 StackAllocationTest
D:\YDIdeaWorkspace\java-test>jstat -gc 3364
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
512.0  512.0  192.0   0.0    2048.0   753.1     7168.0     740.2    4864.0 3837.2 512.0  428.9      **88**    0.030   0      0.000    0.030

启用逃逸分析
-XX:-DoEscapeAnalysis改为-XX:+DoEscapeAnalysis,结果如下

D:\YDIdeaWorkspace\java-test>jstat -gc 4400
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
512.0  512.0   0.0   504.0   2048.0   1089.4    7168.0     296.0    4864.0 3638.7 512.0  400.4       3    0.002   0      0.000    0.002

结果表示启用逃逸分析后,gc的次数从88下降到了3,说明大部分对象并没有在堆上创建

试验2 jmap -histo分析

调高堆容量
-Xmx3G -Xms3G -XX:-DoEscapeAnalysis -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError`
使用jmap分析

D:\YDIdeaWorkspace\java-test>jps
10320 StackAllocationTest
D:\YDIdeaWorkspace\java-test>jmap -histo 10320

 num     #instances         #bytes  class name
----------------------------------------------
   1:      10000000      160000000  org.example.StackAllocationTest$A
....

同理-XX:-DoEscapeAnalysis改为-XX:+DoEscapeAnalysis后:

D:\YDIdeaWorkspace\java-test>jmap -histo 4976
 num     #instances         #bytes  class name
----------------------------------------------
   1:           770       58405912  [I
   2:          1312        2508296  [B
   3:        118001        1888016  org.example.StackAllocationTest$A
....

可以看到不开启逃逸分析时,堆上A的实例有1000w个;开启后,堆上只有12w不到。侧面反映开启后对象并不在堆上分配空间了!

试验3 默认参数

-Xmx3G
-Xms3G
D:\YDIdeaWorkspace\java-test>jmap -histo 7092
 num     #instances         #bytes  class name
----------------------------------------------
   1:           770       58150768  [I
   2:          1312        2508144  [B
   3:        134017        2144272  org.example.StackAllocationTest$A

可以看到jdk1.8是默认开启的

加入-XX:+PrintFlagsFinal

[Global flags]
     bool DoEscapeAnalysis                          = true                                {C2 product}
     bool EliminateAllocations                      = true                                {C2 product}
     bool EliminateLocks                            = true                                {C2 product}

可以看到逃逸分析默认开启,并且标量替换、同步锁消除 也是默认开启的(这2个需要逃逸分析开启)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值