资讯专栏INFORMATION COLUMN

【深入浅出-JVM】(7):栈上分配

greatwhole / 1622人阅读

摘要:概念对那些作用于不会逃逸出方法的对象,在分配内存时,不在将对象分配在堆内存中,而是将对象属性打散后分配在线程私有栈内存上,这样随着方法调用结束,栈上分配打散的对象也被回收掉,不在增加额外压力。

概念

对那些作用于不会逃逸出方法的对象,在分配内存时,不在将对象分配在堆内存中,而是将对象属性打散后分配在线程私有栈内存上,这样随着方法调用结束,栈上分配打散的对象也被回收掉,不在增加 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,

感谢您的耐心阅读,如果您发现文章中有一些没表述清楚的,或者是不对的地方,请给我留言,您的鼓励是作者写作最大的动力。

作 者 : @mousycoder

原文出处 : http://mousycoder.com/thinking-in-jvm/7/

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/75376.html

相关文章

  • Java中的逃逸分析

    摘要:当一个对象被定义之后,可能会被外部对象引用,称之为方法逃逸也有可能被其他线程所引用,称之为线程逃逸。在编译过程中,经过逃逸分析确定一个对象不会被其他线程或者方法访问,那么会将对象的创建替换成为多个成员变量的创建,称之为标量替换。 1.引言 Java 程序运行时,JVM 会将 .class 字节码转换成机器能够识别的指令,指令转换过程会产生耗时,延缓程序的运行速度,为了解决这种问题出现了...

    jayce 评论0 收藏0
  • Java对象分配简要流程

    摘要:在一般应用中,不会逃逸的局部对象所占的比例很大,如果能使用栈上分配,那大量的对象就会随着方法的结束而自动销毁了,垃圾收集系统的压力将会小很多。相关参数设置大对象直接进入年老代的阈值,当对象大小超过这个值时,将直接在年老代分配。 jvm系列 垃圾回收基础 JVM的编译策略 GC的三大基础算法 GC的三大高级算法 GC策略的评价指标 JVM信息查看 GC通用日志解读 jvm的card t...

    zorro 评论0 收藏0
  • JVM解剖公园

    摘要:为此,引入转换查找缓冲缓存最近的转换记录。这个优化技术,可以看到将原本对对象的字段访问,替换为一个局部变量的访问。当所有线程都在已知的位置停止的时候,被认为是到达了安全点。检查安全点请求的代码 showImg(https://segmentfault.com/img/bVbwfcz?w=1024&h=576); 1、JVM锁粗化和循环原文标题:JVM Anatomy Quark #1:...

    imingyu 评论0 收藏0
  • JVM从小白学成大佬】2.Java虚拟机运行时数据区

    摘要:虚拟机在执行程序的过程中会把它所管理的内存划分为若干个不同的数据区域。栈帧栈帧是用于支持虚拟机进行方法调用和方法执行的数据结构,它是虚拟机运行时数据区中的虚拟机栈的栈元素。栈帧的概念结构如下运行时数据区脑图高 这里我们先说句题外话,相信大家在面试中经常被问到介绍Java内存模型,我在面试别人时也会经常问这个问题。但是,往往都会令我比较尴尬,我还话音未落,面试者就会背诵一段(Java虚拟...

    shuibo 评论0 收藏0
  • JVM的编译策略

    摘要:解释器与编译器并存如果选用完全解释策略,那么编译器将停止所有的工作,字节码将完全依靠解释器逐行解释执行。如果选用完全编译策略,那么解释器仍然会在编译器无法进行的特殊情况下介入运行,这主要是确保程序能够最终顺序执行。 jvm系列 垃圾回收基础 JVM的编译策略 GC的三大基础算法 GC的三大高级算法 GC策略的评价指标 JVM信息查看 GC通用日志解读 jvm的card table数据...

    CloudwiseAPM 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<