JVM内存逃逸[通俗易懂]

JVM内存逃逸[通俗易懂]JVM内存逃逸第一次听到JVM内存逃逸的名词时还是很懵逼的,于是赶紧各种查资料,终于搞懂了这个地方。JVM的内存分配主要在是运行时数据区(RuntimeDataAreas),而运行时数据区又分为了:方法区,堆区,PC寄存器,Java虚拟机栈(就是栈区,官方文档还是叫Java虚拟机栈),本地方法区,而内存逃逸主要是对象的动态作用域的改变而引起的,故而内存逃逸的分析就是分析对象的动态作…

大家好,又见面了,我是你们的朋友全栈君。

JVM内存逃逸

  • 第一次听到JVM内存逃逸的名词时还是很懵逼的,于是赶紧各种查资料,终于搞懂了这个地方。

  • JVM的内存分配主要在是运行时数据区(Runtime Data Areas),而运行时数据区又分为了:方法区堆区PC寄存器Java虚拟机栈(就是栈区,官方文档还是叫Java虚拟机栈)本地方法区,而内存逃逸主要是对象的动态作用域的改变而引起的,故而内存逃逸的分析就是分析对象的动态作用域。

  • 方法逃逸

    • 什么是方法逃逸呢?举个栗子,在一个方法中定义一个对象后(方法内局部的),这个对象被外部方法引用,比如作为返回值返回传递到其他的地方,当这个方法执行结束要进行GC时,这个方法中的对象本应该被回收,却发现该对象还是存活状态没法回收,就称为方法逃逸

    • 上代码:

      public static StringBuffer getStringBuffer(String str1,String str2) { 
             
          StringBuffer stringBuffer = new StringBuffer();
          stringBuffer.append(str1);
          stringBuffer.append(str2);
          return stringBuffer;
      }
      

      上面的代码中的stringBuffer虽然是方法内的局部变量,因为stringBuffer被当作返回值返回,这样stringBuffer可能被其他的方法所改变,作用域就不仅仅在本方法内啦,这样就是逃逸到了方法外部。对的,就是越狱了。

    • 怎么样才能不让stringBuffer逃出方法呢?那么不直接返回stringBuffer对象不就可以了嘛!如下面的代码:

      public static StringBuffer getStringBuffer(String str1,String str2) { 
             
          StringBuffer stringBuffer = new StringBuffer();
          stringBuffer.append(str1);
          stringBuffer.append(str2);
          return stringBuffer.toString();
      }
      
  • 线程逃逸:上面的例子,直接将对象返回,该对象可能被外部线程访问,如:赋值给类变量等,称为线程逃逸。

  • 总的来说就是一个对象的指针被多个方法或者线程引用时,我们就称这个对象的指针发生了逃逸。

  • 优化:即证明一个对象不会逃逸到方法或线程外。

    • 栈上分配

      说起对象,那你第一个想到的是在堆空间上进行内存分配,GC在堆空间上筛选可回收的对象,回收对象,整理内存都需要浪费时间,若能通过逃逸分析确定某些对象是一定不会逃逸出方法之外的,就可以直接让这个对象在栈上分配内存,该对象随方法的执行结束栈帧出栈而销毁,减轻了GC的压力。

    • 同步消除

      线程同步本身比较耗时,若确定了一个变量不会逃逸出线程,无法被其他线程访问到,那这个变量的读写就不会存在竞争,这个变量的同步措施就可以清除掉。

    • 标量替换

      标量:Java中的原始数据类型(int,char,long等)都不能再进一步分解,他们就可以称为标量。

      聚合量:若一个数据可以继续分解,那就称之为聚合量,而对象就是典型的聚合量。

      若逃逸分析证明一个对象不会逃逸出方法,不会被外部访问,并且这个对象是可以被分解的,那程序在真正执行的时候可能不创建这个对象,而是直接创建这个对象分解后的标量来代替。这样就无需在对对象分配空间了,只在栈上为分解出的变量分配内存即可。

  • All in all

    • 逃逸分析是比较耗时的,所以性能未必提升很多,因为其耗时性,采用的算法都是不那么准确但是时间压力相对较小的算法来完成的,这就可能导致效果不稳定,要慎用。
    • 由于HotSpot虚拟机目前的实现方法导致栈上分配实现起来比较复杂,所以HotSpot虚拟机中暂时还没有这项优化。
    • 相关的JVM参数
      • -XX:+DoEscapeAnalysis 开启逃逸分析、
      • -XX:+PrintEscapeAnalysis 开启逃逸分析后,可通过此参数查看分析结果。
      • -XX:+EliminateAllocations 开启标量替换
      • -XX:+EliminateLocks 开启同步消除
      • -XX:+PrintEliminateAllocations 开启标量替换后,查看标量替换情况。

感谢阅读~
希望能对您有帮助~
给孩子留个赞吧~

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/138962.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 微信公众号发布提醒(微信公众号模板消息接口)

    1.项目简介灵感来源于学校的每日健康日报,要求使用微信小程序进行每日健康打卡。所以此项目的功能类似于QQ群机器人,或者是每日闹钟。功能描述:用户访问给定的页面,进行授权登录,然后确认自己的身份(本科生或研究生),并开启通知,即可每天在约定时间收到微信服务号的消息提醒。当然,用户可以自定义每日通知的时间,也可以随时开启或关闭每日通知。

    2022年4月12日
    420
  • intellij idea快速生成main方法、for循环、out输出

    intellij idea快速生成main方法、for循环、out输出点击这里查看<intellijidea使用教程汇总篇>1、System.out.println()输入sout,按下enter键,生成System.out.println()方法.sout—>soutv=System.out.println("变量名 = " + 变量)soutp—>System.out.println("")2、public…

    2022年5月6日
    161
  • 谷歌浏览器搜索使用指南[通俗易懂]

    谷歌浏览器搜索使用指南[通俗易懂]谷歌浏览器使用指南下载谷歌浏览器使用浏览器时遇到的问题对谷歌浏览器进行配置下载谷歌浏览器可以在谷歌浏览器官网进行下载,网址:https://www.google.cn/intl/zh-CN/chrome/在腾讯电脑管家,进行下载使用浏览器时遇到的问题搜索引擎我们这里先选用百度搜索引擎,如果想使用其他搜索引擎,更换其他的网址即可。1.当你使用谷歌浏览器时你会发现,根本上不了网2.这个时候你不要惊慌,自己在网址框中手动输入:https://www.baidu.com/即可进行上网对谷

    2022年9月10日
    0
  • 数据库课程设计-宿舍管理系统「建议收藏」

    数据库课程设计-宿舍管理系统「建议收藏」最近写完了数据库的课程设计,想把整个源码的编辑过程发出来。程序很简单,需要有很多完善的地方,在这里,我想和大家分享写这个程序的心路历程。首先,在开始写程序之前。我们需要先写一些工具类,来辅助完成整个程序的构建,在这里我把连接jdbc的代码放在了一个包下面。如下图:在这里我们先来写最基本的类,jdbcDrive,这是负责和数据库进行连接,并且执行语句的类publ…

    2022年5月19日
    28
  • pwm波控制舵机原理(转)[通俗易懂]

    pwm波控制舵机原理(转)[通俗易懂]文章转自:http://www.geek-workshop.com/thread-70-1-1.html一、关于舵机:舵机(英文叫Servo):它由直流电机、减速齿轮组、传感器和控制电路组成的一套自动控制系统。通过发送信号,指定输出轴旋转角度。舵机一般而言都有最大旋转角度(比如180度。)与普通直流电机的区别主要在,直流电机是一圈圈转动的,舵机只能在一定角度内转动,不能一圈圈转(数字舵机可…

    2022年6月17日
    31
  • 大数据开发工程师需要掌握什么技能?

    大数据开发工程师需要掌握什么技能?

    2021年7月2日
    90

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号