Java对象逃逸
关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。
专注于分享各领域原创系列文章 ,擅长java后端、移动开发、商业变现、人工智能等,希望大家多多支持。
未经允许不得转载
目录
- 一、导读
- 二、概览
- 三、相关知识
- 3.1 逃逸分析
- 3.2 对象逃逸状态
- 3.3 Java中的对象都是在堆中分配吗?说明为什么!
- 四、 推荐阅读

一、导读
我们继续总结学习Java基础知识,温故知新。
逃逸分析的基本行为就是分析对象动态作用域:当一个对象在方法中被定义后,它可能被外部方法所引用,例如作为调用参数传递到其他地方中,称为方法逃逸。
二、概览
Java对象逃逸指的是一个对象在其应该被限制访问的范围之外被引用或访问的情况,简单解释就是我有一个方法,在方法内创建了一个对象,但是这个对象传递到其他地方了。
在Java中,对象一般在包含它们的方法中创建和使用,当方法结束时,这些对象会被回收。然而,当对象在方法中被引用或传递到其他方法中时,就会发生对象逃逸。
我们举例
这种写法直接返回的是对象,用处就是被别的变量所引用,会造成对象逃逸,从而增加了GC的压力。public StringBuilder getSb(){StringBuilder sb = new StringBuilder("");return sb;}不如改成下面这样public String getSb1(){StringBuilder sb = new StringBuilder("");return sb.toString();}
第一段代码中的sb就逃逸了,而第二段代码中的sb就没有逃逸。
三、相关知识
在这之前,我们要先了解一些jvm的基本知识。

Java运行时数据区(Runtime Data Area)是指在Java程序执行期间,Java虚拟机所管理的诸多内存区域(分别用于存储不同的数据),如上图所示,包含了以下几个部分:
- 堆区 (主要用于存储对象实例、数组)
- 栈区 (主要存放java方法、局部变量、操作数栈、动态链接、方法出口、基本类型的变量数据、对象的引用等)
- 方法区 (主要用于存储类型信息、常量、静态变量、即时编译代码等)
- 程序计数器
一个Java的源代码文件变成计算机可执行的机器指令的过程中,需要经过两段编译,
第一段是把.java文件转换成.class文件。
第二段是把.class转换成机器指令的过程,JVM 通过解释字节码将其翻译成对应的机器指令,逐条读入,逐条解释翻译,后来为了解决效率问题,引入了 JIT(即时编译) 技术。
JIT会对代码做很多优化。其中有一部分优化的目的就是减少内存堆分配压力,其中一种重要的技术叫做逃逸分析。通过逃逸分析,Java Hotspot编译器能够
分析出一个新的对象的引用的使用范围从而决定是否要将这个对象分配到堆上。逃逸分析的基本行为就是分析对象动态作用域
public static StringBuffer craeteStringBuffer(String s1, String s2) {StringBuffer sb = new StringBuffer();sb.append(s1);sb.append(s2);return sb;
}sb是一个方法内部变量,上述代码中直接将sb返回,这样这个sb 有可能被其他方法所改变,这样它的作用域就不只是在方法内部
3.1 逃逸分析
逃逸分析(Escape Analysis)简单来讲就是,Java Hotspot 虚拟机可以分析新创建对象的使用范围,并决定是否在 Java 堆上分配内存的一项技术。
在Java代码运行时,通过JVM参数可指定是否开启逃逸分析,
- -XX:+DoEscapeAnalysis : 开启逃逸分析. 从jdk 1.7开始已经默认开始逃逸分析
- -XX:-DoEscapeAnalysis : 关闭逃逸分析 。
- -XX:+PrintEscapeAnalysis : 显示分析结果
使用逃逸分析,编译器可以对代码做如下优化:
- 同步省略 (锁消除)
public void f() {Object hollis = new Object();synchronized(hollis) {System.out.println(hollis);}
}优化后变成
public void f() {Object hollis = new Object();System.out.println(hollis);
}
- 分离对象或标量替换
- 将堆分配转化为栈分配
当对象没有发生逃逸时,要使指向该对象的指针永远不会逃逸,对象可能是栈分配的候选,而不是堆分配,该对象就可以通过标量替换分解成成员标量分配在栈内存中,
和方法的生命周期一致,随着栈帧出栈时销毁,减少了 GC 压力,提高了应用程序性能
3.2 对象逃逸状态
1、全局逃逸(GlobalEscape)
即一个对象的作用范围逃出了当前方法或者当前线程,有以下几种场景:
- 对象是一个静态变量
- 对象是一个已经发生逃逸的对象
- 对象作为当前方法的返回值
2、参数逃逸(ArgEscape)
即一个对象被作为方法参数传递或者被参数引用,但在调用过程中不会发生全局逃逸,这个状态是通过被调方法的字节码确定的。
对象逃逸可能会导致以下问题:
- 安全问题:对象逃逸可以使对象暴露给不受信任的代码,可能导致数据泄露或被篡改。
- 性能问题:对象逃逸可能导致对象的生命周期变得不可预测,增加垃圾回收的负担,降低系统性能。
- 并发问题:对象逃逸可能导致多个线程同时访问同一个对象,造成线程安全问题。
为了解决对象逃逸问题,可以采取以下措施:
- 限制对象的访问范围:将对象的作用域限制在方法内部,避免在方法外部引用或传递对象。
- 使用局部变量代替成员变量:将对象定义为方法内的局部变量而不是成员变量,这样可以避免对象在方法外部被引用。
- 使用不可变对象:如果对象是不可变的,那么即使发生逃逸,也不会出现安全和并发问题。
- 使用线程安全的数据结构:如果对象需要在多个线程之间共享,应该使用线程安全的数据结构或采用同步控制机制来保证并发安全性。
通过避免对象逃逸,可以提高代码的安全性、性能和并发性能。
3.3 Java中的对象都是在堆中分配吗?说明为什么!
对象和数组并不一定都在堆上分配内存的,随着JIT编译器的发展,在编译期间,如果JIT经过逃逸分析,发现有些对象没有逃逸出方法,
那么有可能堆内存分配会被优化成栈内存分配,
JIT编译器就可以在编译期间根据逃逸分析的结果,来决定是否可以将对象的内存分配从堆转化为栈。
举个栗子:
先定义一个类 XYZclass XYZ {int i;
}在定义一个方法 abc(),方法内使用了XYZ类,但是并没有外部引用,也就说这个对象不会发生逃逸。public void abc() {XYZ xyz = new XYZ();
}最后再定义一个for循环来调用abc()方法,假设我们在代码中创建100万个XYZ对象,for (int i = 0; i < 1000000; i++) {abc();}
假设我们先关闭逃逸分析,在代码结束前使用[jmap][1]命令,来查看下当前堆内存中有100万个XYZ对象.
-Xmx4G -Xms4G -XX:-DoEscapeAnalysis -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError
接下来,我们开启逃逸分析,再来执行下以上代码,使用jmap命令,来查看下当前堆内存中有几万个XYZ对象,不是一个量级。
堆内存中分配的对象数量大量减少,
-Xmx4G -Xms4G -XX:+DoEscapeAnalysis -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError
四、 推荐阅读
Java 专栏
SQL 专栏
数据结构与算法
Android学习专栏
未经允许不得转载

相关文章:
Java对象逃逸
关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 ,擅长java后端、移动开发、商业变现、人工智能等,希望大家多多支持。 未经允许不得转载 目录 一、导读二、概览三、相关知识3.1 逃逸…...
Greenplum的数据库年龄检查处理
概述 Greenplum是基于Postgresql数据库的分布式数据库,而PG数据库在事务及多版本并发控制的实现方式上很特别,采用的是递增事务id的方法,事务id大的事务,认为比较新,反之事务id小,认为比较旧。 事务id的上…...
[HCIE] IPSec-VPN (IKE自动模式)
概念: IKE:因特网密钥交换 实验目标:pc1与pc2互通 步骤1:R1与R3配置默认路由 R1: ip route-static 0.0.0.0 0.0.0.0 12.1.1.2 R2: ip route-static 0.0.0.0 0.0.0.0 23.1.1.2 步骤2:配ACL…...
Qt/QML编程学习之心得:一个Qt工程的学习笔记(九)
这里是关于如何使用Qt Widget开发,而Qt Quick/QML的开发是另一种方式。 1、.pro文件 加CONFIG += c++11,才可以使用Lamda表达式(一般用于connect的内嵌槽函数) 2、QWidget 这是Qt新增加的一个类,基类,窗口类,QMainWindow和QDialog都继承与它。 3、Main函数 QApplicati…...
c++ 课程笔记
105课: cpp文件分为 .h .cpp .cpp 文件 110课:124课 深拷贝 浅拷贝 自建拷贝构造解决浅拷贝释放new后堆区析构函数的问题 (浅拷贝 拷贝内存地址, 释放堆区时 导致源数据 释放时,该地址无数据?而报错) 浅拷贝: 拷贝了对方的值和 堆区内存地址(删除 影响原数据堆区) 深拷贝…...
ELK企业级日志分析平台——ES集群监控
启用xpack认证 官网:https://www.elastic.co/guide/en/elasticsearch/reference/7.6/configuring-tls.html#node-certificates 在elk1上生成证书 [rootelk1 ~]# cd /usr/share/elasticsearch/[rootelk1 elasticsearch]# bin/elasticsearch-certutil ca[rootelk1 ela…...
Twincat使用:EtherCAT通信扫描硬件设备链接PLC变量
EtherCAT通信采用主从架构,其中一个主站设备负责整个EtherCAT网络的管理和控制,而从站设备则负责在数据环网上传递数据。 主站设备可以是计算机、工控机、PLC等, 而从站设备可以是传感器、执行器、驱动器等。 EL3102:MDP5001_300_CF8D1684;…...
手机APP-MCP走蓝牙无线遥控智能安全帽~执法记录仪~拍照录像,并可做基础的配置,例如修改服务器IP以及配置WiFi等
手机APP-MCP走蓝牙无线遥控智能安全帽~执法记录仪~拍照录像,并可做基础的配置,例如修改服务器IP以及配置WiFi等 手机APP-MCP走蓝牙无线遥控智能安全帽~执法记录仪~拍照录像,并可做基础的配置,例如修改服务器IP以及配置WiFi等, AIoT万物智联,智能安全帽…...
网络互联与IP地址
目录 网络互联概述网络的定义与分类网络的定义网络的分类 OSI模型和DoD模型网络拓扑结构总线型拓扑结构星型拓扑结构环型拓扑结构 传输介质同轴电缆双绞线光纤 介质访问控制方式CSMA/CD令牌 网络设备网卡集线器交换机路由器总结 IP地址A、B、C类IP地址特殊地址形式 子网与子网掩…...
Android设计模式--模板方法模式
一,定义 定义一个操作中的算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 在面向对象的开发过程中,通常会遇到这样一个问题,我们知道一个算法所需的关键步…...
大语言模型——BERT和GPT的那些事儿
前言 自然语言处理是人工智能的一个分支。在自然语言处理领域,有两个相当著名的大语言模型——BERT和GPT。两个模型是同一年提出的,那一年BERT以不可抵挡之势,让整个人工智能届为之震动。据说当年BERT的影响力是GPT的十倍以上。而现在&#…...
Docker 命令详解
1. 容器生命周期管理 命令说明文档run创建一个新的容器并运行一个命令Docker run 命令start/stop/restart启动、停止、重启容器Docker start/stop/restart 命令kill杀掉一个运行中的容器Docker kill 命令rm删除一个或多个容器Docker rm 命令pause/unpause暂停 恢复容器中所有的…...
ios打包,证书获取
HBuilderX 打包ios界面: Bundle ID(AppID): 又称应用ID,是每一个ios应用的唯一标识,就像一个人的身份证号码; 每开发一个新应用,首先都需要先去创建一个Bundle ID Bundle ID 格式: 一般为&…...
linux(nginx安装配置,tomcat服务命令操作)
首先进系统文件夹 /usr/lib/systemd/systemLs | grep mysql 查看带有命名有MySQL的文件夹修改tomcat.service文件复制jdk目录替换成我们的路径替换成我们的路径进入这个目录,把修改好的文件拖到我们的工具里面重新刷新系统 systemctl daemon-reload查看tomcat状态…...
jQuery_03 dom对象和jQuery对象的互相转换
dom对象和jQuery对象 dom对象 jQuery对象 在一个文件中同时存在两种对象 dom对象: 通过js中的document对象获取的对象 或者创建的对象 jQuery对象: 通过jQuery中的函数获取的对象。 为什么使用dom或jQuery对象呢? 目的是 要使用dom对象的函数或者属性 以及呢 要…...
Mysql 中如何导入数据?
文章目录 前言使用 LOAD DATA 导入数据使用 mysqlimport 导入数据mysqlimport的常用选项介绍后言 前言 hello world欢迎来到前端的新世界 😜当前文章系列专栏:Mysql 🐱👓博主在前端领域还有很多知识和技术需要掌握,正…...
深入了解前馈网络、CNN、RNN 和 Hugging Face 的 Transformer 技术!
一、说明 本篇在此对自然语言模型做一个简短总结,从CNN\RNN\变形金刚,和抱脸的变形金刚库说起。 二、基本前馈神经网络: 让我们分解一个基本的前馈神经网络,也称为多层感知器(MLP)。此代码示例将࿱…...
Flink Table API 读写MySQL
Flink Table API 读写 MySQL import org.apache.flink.connector.jdbc.table.JdbcConnectorOptions; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.table.api.DataTypes; import org.apache.flink.table.api.Envi…...
Nginx 开源版安装
下载 tar.gz安装包,上传。 解压 [rootlocalhost ~]# tar zxvf nginx-1.21.6.tar.gz nginx-1.21.6/ nginx-1.21.6/auto/ nginx-1.21.6/conf/ nginx-1.21.6/contrib/ nginx-1.21.6/src/ ... ...安装gcc [rootlocalhost nginx-1.21.6]# yum install -y gcc 已加载插件…...
『亚马逊云科技产品测评』活动征文|低成本搭建物联网服务器thingsboard
授权声明:本篇文章授权活动官方亚马逊云科技文章转发、改写权,包括不限于在 Developer Centre, 知乎,自媒体平台,第三方开发者媒体等亚马逊云科技官方渠道。 0. 环境 - ubuntu22(注意4G内存勉强够,部署完…...
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...
消息队列系统设计与实践全解析
文章目录 🚀 消息队列系统设计与实践全解析🔍 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡💡 权衡决策框架 1.3 运维复杂度评估🔧 运维成本降低策略 🏗️ 二、典型架构设计2.1 分布式事务最终一致…...
LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》
🧠 LangChain 中 TextSplitter 的使用详解:从基础到进阶(附代码) 一、前言 在处理大规模文本数据时,特别是在构建知识库或进行大模型训练与推理时,文本切分(Text Splitting) 是一个…...
负载均衡器》》LVS、Nginx、HAproxy 区别
虚拟主机 先4,后7...
