当前位置: 首页 > news >正文

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)
即一个对象被作为方法参数传递或者被参数引用,但在调用过程中不会发生全局逃逸,这个状态是通过被调方法的字节码确定的。

对象逃逸可能会导致以下问题:

  1. 安全问题:对象逃逸可以使对象暴露给不受信任的代码,可能导致数据泄露或被篡改。
  2. 性能问题:对象逃逸可能导致对象的生命周期变得不可预测,增加垃圾回收的负担,降低系统性能。
  3. 并发问题:对象逃逸可能导致多个线程同时访问同一个对象,造成线程安全问题。

为了解决对象逃逸问题,可以采取以下措施:

  1. 限制对象的访问范围:将对象的作用域限制在方法内部,避免在方法外部引用或传递对象。
  2. 使用局部变量代替成员变量:将对象定义为方法内的局部变量而不是成员变量,这样可以避免对象在方法外部被引用。
  3. 使用不可变对象:如果对象是不可变的,那么即使发生逃逸,也不会出现安全和并发问题。
  4. 使用线程安全的数据结构:如果对象需要在多个线程之间共享,应该使用线程安全的数据结构或采用同步控制机制来保证并发安全性。

通过避免对象逃逸,可以提高代码的安全性、性能和并发性能。

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学习专栏

未经允许不得转载

ddd

相关文章:

Java对象逃逸

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、商业变现、人工智能等&#xff0c;希望大家多多支持。 未经允许不得转载 目录 一、导读二、概览三、相关知识3.1 逃逸…...

Greenplum的数据库年龄检查处理

概述 Greenplum是基于Postgresql数据库的分布式数据库&#xff0c;而PG数据库在事务及多版本并发控制的实现方式上很特别&#xff0c;采用的是递增事务id的方法&#xff0c;事务id大的事务&#xff0c;认为比较新&#xff0c;反之事务id小&#xff0c;认为比较旧。 事务id的上…...

[HCIE] IPSec-VPN (IKE自动模式)

概念&#xff1a; IKE&#xff1a;因特网密钥交换 实验目标&#xff1a;pc1与pc2互通 步骤1&#xff1a;R1与R3配置默认路由 R1&#xff1a; ip route-static 0.0.0.0 0.0.0.0 12.1.1.2 R2&#xff1a; ip route-static 0.0.0.0 0.0.0.0 23.1.1.2 步骤2&#xff1a;配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认证 官网&#xff1a;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通信采用主从架构&#xff0c;其中一个主站设备负责整个EtherCAT网络的管理和控制&#xff0c;而从站设备则负责在数据环网上传递数据。 主站设备可以是计算机、工控机、PLC等&#xff0c; 而从站设备可以是传感器、执行器、驱动器等。 EL3102:MDP5001_300_CF8D1684;…...

手机APP-MCP走蓝牙无线遥控智能安全帽~执法记录仪~拍照录像,并可做基础的配置,例如修改服务器IP以及配置WiFi等

手机APP-MCP走蓝牙无线遥控智能安全帽~执法记录仪~拍照录像,并可做基础的配置,例如修改服务器IP以及配置WiFi等 手机APP-MCP走蓝牙无线遥控智能安全帽~执法记录仪~拍照录像,并可做基础的配置,例如修改服务器IP以及配置WiFi等&#xff0c; AIoT万物智联&#xff0c;智能安全帽…...

网络互联与IP地址

目录 网络互联概述网络的定义与分类网络的定义网络的分类 OSI模型和DoD模型网络拓扑结构总线型拓扑结构星型拓扑结构环型拓扑结构 传输介质同轴电缆双绞线光纤 介质访问控制方式CSMA/CD令牌 网络设备网卡集线器交换机路由器总结 IP地址A、B、C类IP地址特殊地址形式 子网与子网掩…...

Android设计模式--模板方法模式

一&#xff0c;定义 定义一个操作中的算法的框架&#xff0c;而将一些步骤延迟到子类中&#xff0c;使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 在面向对象的开发过程中&#xff0c;通常会遇到这样一个问题&#xff0c;我们知道一个算法所需的关键步…...

大语言模型——BERT和GPT的那些事儿

前言 自然语言处理是人工智能的一个分支。在自然语言处理领域&#xff0c;有两个相当著名的大语言模型——BERT和GPT。两个模型是同一年提出的&#xff0c;那一年BERT以不可抵挡之势&#xff0c;让整个人工智能届为之震动。据说当年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界面&#xff1a; Bundle ID(AppID)&#xff1a; 又称应用ID&#xff0c;是每一个ios应用的唯一标识&#xff0c;就像一个人的身份证号码&#xff1b; 每开发一个新应用&#xff0c;首先都需要先去创建一个Bundle ID Bundle ID 格式&#xff1a; 一般为&…...

linux(nginx安装配置,tomcat服务命令操作)

首先进系统文件夹 /usr/lib/systemd/systemLs | grep mysql 查看带有命名有MySQL的文件夹修改tomcat.service文件复制jdk目录替换成我们的路径替换成我们的路径进入这个目录&#xff0c;把修改好的文件拖到我们的工具里面重新刷新系统 systemctl daemon-reload查看tomcat状态…...

jQuery_03 dom对象和jQuery对象的互相转换

dom对象和jQuery对象 dom对象 jQuery对象 在一个文件中同时存在两种对象 dom对象: 通过js中的document对象获取的对象 或者创建的对象 jQuery对象: 通过jQuery中的函数获取的对象。 为什么使用dom或jQuery对象呢&#xff1f; 目的是 要使用dom对象的函数或者属性 以及呢 要…...

Mysql 中如何导入数据?

文章目录 前言使用 LOAD DATA 导入数据使用 mysqlimport 导入数据mysqlimport的常用选项介绍后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;Mysql &#x1f431;‍&#x1f453;博主在前端领域还有很多知识和技术需要掌握&#xff0c;正…...

深入了解前馈网络、CNN、RNN 和 Hugging Face 的 Transformer 技术!

一、说明 本篇在此对自然语言模型做一个简短总结&#xff0c;从CNN\RNN\变形金刚&#xff0c;和抱脸的变形金刚库说起。 二、基本前馈神经网络&#xff1a; 让我们分解一个基本的前馈神经网络&#xff0c;也称为多层感知器&#xff08;MLP&#xff09;。此代码示例将&#xff1…...

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安装包&#xff0c;上传。 解压 [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

授权声明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 Developer Centre, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道。 0. 环境 - ubuntu22&#xff08;注意4G内存勉强够&#xff0c;部署完…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...