如何理解JVM本地方法栈&堆

这期内容当中小编将会给大家带来有关如何理解JVM本地方法栈&堆,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

创新互联建站主营耒阳网站建设的网络公司,主营网站建设方案,app开发定制,耒阳h5小程序定制开发搭建,耒阳网站营销推广欢迎耒阳等地区企业咨询

今天我们一起了解一下关于本地方法栈和Java堆的相关知识。

 
本地方法栈

本地方法栈与Java虚拟机栈发挥的作用相同,区别在于Java虚拟机栈是为虚拟机执行Java方法服务,而本地方法栈是为虚拟机执行Native方法服务。

 
Java堆

Java堆是虚拟机管理的最大的一块内存区域,堆主要用来存放对象的实例。Java堆主要分为:

  • 新生代(Eden)
  • 老年代
  • Survivor(s0、s1也可以成为from、to,属于新生代)

在绝大数情况下,对象都会被分配在新生代,在经历过一次新生代回收后,如果对象还存活那么会进入s0或者s1,每经过一次新生代回收,如果对象存活那么他的年龄将会加,当对象的年龄到达一定的条件时会进入老年代。当然如果对象非常大,超出了新生代的大小,对象也有可能直接分配在老年代。

随着JIT编译器的发展以及逃逸分析技术的成熟,栈上分配、标量替换等技术使得对象分配在堆中变得不再那么绝对。

 
栈上分配

栈上分配是指对那些线程私有的对象可以将他们打散分散在栈上,分配在栈上的好处是随着函数调用结束对象自动销毁,不需要垃圾回收器的介入,从而提高系统的性能。

栈上分配的基础是要进行逃逸分析,逃逸分析的目的是判断对象的作用域是否可能逃出函数体。

逃逸分析只有在Server模式下才可以启动(这个作者由于本人Java环境是Server环境,没有做验证,如果有读者感兴趣,可以使用Client模式启动做一下验证然后截图留言)。参数是:

  • -XX:+DoEscapeAnalysis
public class EscapeAnalysis {
   public static class User {        private int id = 1;        private String name = "xiaoming";    }
   public static void alloc() {        User u = new User();        u.id = 5;        u.name = "xiaohong";    }
   public static void main(String[] args) {        long start = System.currentTimeMillis();        for (int i = 0; i < 100000000; i++) {            alloc();        }        long end = System.currentTimeMillis();        System.out.println(end - start);    }}
 

执行以下命令将源码文件编译成字节码文件并且运行字节码

javac -d . EscapeAnalysis.javajava -server -Xmx10m -Xms10m -XX:-DoEscapeAnalysis -XX:+PrintGC jvm/heap/EscapeAnalysis
 

由于Java8默认开启了逃逸分析,所以我们用-XX:-DoEscapeAnalysis移除逃逸分析看一下效果。

如何理解JVM本地方法栈&堆  


通过上图我们发现由于对象分配在堆上,但我们指定的最大堆为10m,不够存储我们大量User对象,因此虚拟机需要不停的进行垃圾回收来释放堆空间,程序执行时间928ms。

下面我们通过-XX:-EliminateAllocations将标量替换关闭,也就是说不允许对象打散分配在栈上。

java -server -Xmx10m -Xms10m -XX:+DoEscapeAnalysis -XX:-EliminateAllocations -XX:+PrintGC jvm/heap/EscapeAnalysis
 
如何理解JVM本地方法栈&堆  


当我们关闭标量替换以后,会发现对象依旧不能在栈上分配。

下面让我们看一下当我们打开逃逸分析和标量替换(允许Use对象的id和name当做局部变量在栈上存储时)执行效果:

java -server -Xmx10m -Xms10m -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:+PrintGC jvm/heap/EscapeAnalysis
 
如何理解JVM本地方法栈&堆  


通过上图可以看出,我们的程序只进行了一次垃圾回收,总运行时间5ms,相比之前接近1s中的运行时间性能翻了将近200倍,可见由于栈上分配的优化,使得小对象可以直接分配在栈上,避免了垃圾回收器的介入,大幅度提高了我们程序的性能。

栈上分配需要同时开启逃逸分析和标量替换,Java8 Server模式下这两个参数都是默认开启的。

上述就是小编为大家分享的如何理解JVM本地方法栈&堆了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注创新互联行业资讯频道。

分享标题:如何理解JVM本地方法栈&堆
分享地址:https://www.cdcxhl.com/article6/jgseog.html

成都网站建设公司_创新互联,为您提供全网营销推广网站内链网站收录网站设计虚拟主机面包屑导航

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

微信小程序开发