Loading [MathJax]/jax/input/TeX/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >JVM(2): 逃逸分析和内存分配

JVM(2): 逃逸分析和内存分配

作者头像
yiduwangkai
发布于 2019-09-17 07:52:12
发布于 2019-09-17 07:52:12
64100
代码可运行
举报
文章被收录于专栏:大数据进阶大数据进阶
运行总次数:0
代码可运行

首先来说下为什么会有逃逸分析

我们都知道Java对象都是分配在在堆上的,在过往的认识中,一直是以这样的方式存在的,但是从Java7开始支持对象的栈分配和逃逸分析机制。

然后我们来说说具体什么是逃逸分析

逃逸分析是一种能有效减少对象在堆上分配和同步负载的跨函数数据流分析算法,逃逸分析通俗的说就是一个对象的指针被多个线程和方法引用时,那我们就称为这个对象发生了逃逸。

逃逸分析的基本行为就是分析对象动态作用域:当一个对象在方法中被定义后,它可能被外部方法所引用。逃逸分析只能在JIT里完成,不能在静态编译时进行。

逃逸分析又分为方法逃逸和线程逃逸。

方法逃逸:例如作为调用参数传递到其他方法中。 线程逃逸:有可能被外部线程访问到,譬如赋值给类变量或可以在其他线程中访问的实例变量。

主要涉及三种场景,分别是全局变量赋值、方法返回值、实例引用传递。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package me.stormma.gc;
/**
 * <p>Created on 2017/4/21.</p>
 *
 * @author stormma
 *
 * @title <p>逃逸分析</p>
 */
public class EscapeAnalysis {
    public static B b;
    /**
     * <p>全局变量赋值发生指针逃逸</p>
     */
    public void globalVariablePointerEscape() {
        b = new B();
    }
    /**
     * <p>方法返回引用,发生指针逃逸</p>
     * @return
     */
    public B methodPointerEscape() {
        return new B();
    }
    /**
     * <p>实例引用发生指针逃逸</p>
     */
    public void instancePassPointerEscape() {
        methodPointerEscape().printClassName(this);
    }
    class B {
        public void printClassName(EscapeAnalysis clazz) {
            System.out.println(clazz.getClass().getName());
        }
    }
}

逃逸分析主要分为两部分,一个是Java虚拟机进行的逃逸分析,一个是根据逃逸分析原理去优化自己的代码

我们先来说下Java虚拟机的逃逸分析

1.堆对象变成栈对象,一个方法中的对象没有发生逃逸,那么该对象就很有可能被分配在栈上

2.同步消除,逃逸分析可以分析出某个对象是否只有一个线程访问,如果是只有一个线程访问,那么对该对象的同步操作就可以消除,就样就能大大提高并发性和性能。

3.矢量替代,逃逸分析如果发现对象的内存存储结构不需要连续进行的话,就可以将对象的部分甚至全部都保存在CPU寄存器内

下面我们来说下对象的内存分配

为对象分配空间的任务等同于把一块确定大小的内存从Java堆中划分出来。

指针碰撞和空闲列表

指针碰撞对于垃圾收集算法为Serial,ParNew等带compact过程的收集器,该分配算法是假设堆中内存是决对规整的,空闲的在一边,非空闲的在另一边,中间有个指针作为指示器,再要进行内存分配时,只是把指针向空闲的那边移动一段和对象大小相等的空间。

空闲列表只是对于垃圾收集算法为CMS这种基于Mark-sweep算法的收集器,该分配算法是假设堆中的内存是纵横交错的,空闲的和非空闲的交错在一起,对于这种虚拟机就必须维护一个列表,记录那些块是可用的,在要进行内存分配时,从列表中找出一块分配给划分给对象实例,并更新列表上的记录。这种分配方式称为空闲列表。

TLAB

线程本地分配缓冲区(Thread Local Allocation Buffer),由于Java对象一般分配在堆上,在有多个线程需要在堆上申请空间时,那么需要对这些对象的申请进行同步,在有多个对象进行申请时,就会照成分配的效率非常低下,那么使用TLAB就可以避免这种竞争。

TLAB本身占用eden空间,默认是开启的,在开启TLAB的情况下,虚拟机会为每个线程分配一个TLAB空间,开启的设置是:-XX:+UserTLAB,而-XX:+TLABWasteTargetPercent是设置TLAB空间占用eden的空间大小

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
8.JVM内存分配机制超详细解析
之前研究过类的加载过程。具体详情可查看文章:https://www.cnblogs.com/ITPower/p/15356099.html
用户7798898
2021/10/15
1.6K0
jvm 内存分配性能提升之——逃逸分析与tlab
Java从最开始被诟病速度慢,到现在执行速度直追C语言。这些运行时优化是必不可少的。还记得我们之前讲的逃逸分析是怎么回事吗?
一个会写诗的程序员
2021/12/16
9160
jvm 内存分配性能提升之——逃逸分析与tlab
java栈内存初始化,阿里面试官:小伙子,你给我说一下JVM对象创建与内存分配机制吧…
虚拟机遇到一条new指令(new关键字、对象的克隆、对象的序列化等)时,会先去检查这个指令的参数在常量池中定位到一个类的符号引用,并且这个符号引用代表的类是否应被加载过,如果没有那么就去加载该类
全栈程序员站长
2022/08/28
3510
java栈内存初始化,阿里面试官:小伙子,你给我说一下JVM对象创建与内存分配机制吧…
10个经典又容易被人疏忽的JVM面试题
「对象一定分配在堆中吗?」 不一定的,JVM通过「逃逸分析」,那些逃不出方法的对象会在栈上分配。
捡田螺的小男孩
2020/11/26
6860
一文详解JVM对象内存布局以及内存分配规则
对象头可能包含类型指针,通过该指针能确定对象属于哪个类。如果对象是一个数组,那么对象头还会包括数组长度。
架构狂人
2023/08/16
5520
一文详解JVM对象内存布局以及内存分配规则
JVM系列四(内存分配策略).
前面的文章介绍了对象的创建过程,其中第三步 —— 分配内存,只是简单的介绍了分配的方式 —— 指针碰撞、空闲列表,其实内存在堆上分配还大有文章嘞。
JMCui
2019/12/24
8980
JVM系列四(内存分配策略).
JVM简介—1.Java内存区域
Java虚拟机在执行Java程序的过程中,会把它所管理的内存划分为若干个不同的数据区域,这些区域各有各的用途以及各自的创建和销毁时间也不一样。有的区域会随着虚拟机的进程启动而存在,有的区域则依赖用户线程的启动和结束而进而跟着建立和销毁。
东阳马生架构
2025/03/10
840
JVM 对象分配过程
逃逸分析(Escape Analysis)简单来讲就是,Java Hotspot 虚拟机可以分析新创建对象的使用范围,并决定是否在 Java 堆上分配内存的一项技术。
斯武丶风晴
2020/05/09
1.1K0
JVM 对象分配过程
虚拟机篇 之「垃圾收集与内存分配策略」
在 Java 对象被回收之前,首先需要判断该对象是否已经过期或者死亡?常见的判断一个对象是否过期的算法主要有两种,分别为:
CG国斌
2019/05/26
4440
JVM内存分配策略,及垃圾回收算法
说起垃圾收集(Garbage Collection, GC),想必大家都不陌生,它是JVM实现里非常重要的一环,JVM成熟的内存动态分配与回收技术使Java(当然还有其他运行在JVM上的语言,如Scala等)程序员在提升开发效率上获得了惊人的便利。理解GC,对于理解JVM和Java语言有着非常重要的作用。并且当我们需要排查各种内存溢出、内存泄漏问题时,当垃圾收集称为系统达到更高并发量的瓶颈时,只有深入理解GC和内存分配,才能对这些“自动化”的技术实施必要的监控和调节。
李红
2019/09/17
1.2K0
JVM内存分配策略,及垃圾回收算法
对象的创建与内存分配
当 JVM 收到一个 new 指令时,会检查指令中的参数在常量池是否有这个符号的引用,还会检查该类是否已经被加载过了,如果没有的话则要进行一次类加载。
爱明依
2019/04/01
1.2K0
对象的创建与内存分配
Jvm数据区域与垃圾收集<深入了解jvm读书笔记>
周志明老师所著的《深入了解JAVA虚拟机》(后文简称”书中”)可谓是java工程师进阶的必读书籍了.最近读了书中的第一二部分,也就是前五章,有很多收获.因此想要写一篇文章.来用自己理解到的知识来总结一下前五章.
呼延十
2019/08/12
5140
JVM之堆
约定:新生区 <–> 新生代 <–> 年轻代 、 养老区 <–> 老年区 <–> 老年代、 永久区 <–> 永久代
Java微观世界
2025/01/20
1690
JVM之堆
【原创】JVM系列05 | TLAB上分配
Java 程序会极其频繁的创建对象并为对象分配内存空间,一般情况下对象是分配在堆上的,堆又是全局共享的,所以会存在这样一个问题:多个线程同时在堆上申请空间,而堆要同步处理,导致性能下降。
java进阶架构师
2020/06/04
5990
JVM内存分配机制之栈上分配与TLAB的区别
在java开发中,我们普遍认知中,new出的对象是直接分配到堆空间中,而实际情况并非如此,其实大家伙可以思考一下,无论方法的生命周期长与短,只要new的对象就存放在堆中,那么这样只会对jvm的gc产生一个比较大的负担 而前几天在看到jvm调优书中有说到,new出来的对象并非所有都存在堆内存中,其实还有其他另外两个地方可以进行存储new出的对象,称之为栈上分配和TLAB
黎明大大
2020/11/24
2.5K0
JVM内存分配机制之栈上分配与TLAB的区别
JVM之堆
一个进程对应一个jvm实例,同时包含多个线程,这些线==程共享方法区和堆==,每个==线程独有程序计数器、本地方法栈和虚拟机栈==。
程序员阿杜
2021/06/29
9350
3分钟带你了解对象的创建过程
在之前的文章中,我们介绍了类加载的过程和 JVM 内存布局相关的知识。本篇我们综合之前的知识,结合代码一起推演一下对象的真实创建过程,以及对象创建完成之后在 JVM 中是如何保存的。
Java极客技术
2024/02/22
4820
3分钟带你了解对象的创建过程
深入浅出JVM(一)之Hotspot虚拟机中的对象
对象的创建可以分为五个步骤:检查类加载,分配内存,初始化零值,设置对象头,执行实例构造器<init>
菜菜的后端私房菜
2024/09/24
3360
垃圾收集机制与内存分配策略
Java 语言与其他编程语言有一个非常突出的特点,自动化内存管理机制。而这种机制离不开高效率的垃圾收集器(Garbage Collection)与合理的内存分配策略,这也是本篇文章将要描述的两个核心点。
Single
2018/04/04
1.2K2
垃圾收集机制与内存分配策略
JVM性能优化系列-(1) Java内存区域
Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。主要包括:程序计数器、虚拟机栈、本地方法栈、Java堆、方法区(运 行时常量池)、直接内存。
码老思
2023/10/19
4530
JVM性能优化系列-(1) Java内存区域
相关推荐
8.JVM内存分配机制超详细解析
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验