理解Java中的逃逸分析
名词解释:
JIT(Just-In-Time Compilation):实时编译。
有关JIT的概念,可以看我的另一篇文章:《JIT实时编译特性》
在JVM的实现中,为了提高JVM的性能和节省内存空间,JVM提供了一种叫做 “逃逸分析” 的特性,而且对于“逃逸分析” 这种特性,也是近年来大厂面试常问的知识点。今天,我们就一起来聊聊什么是逃逸分析。
逃逸分析的官方定义:一种确定指针动态范围的静态分析,它可以分析在程序的哪些地方可以访问到指针。
很难理解对不对,简单点说就是:一种分析手段,用于确定对象的作用范围。
分析的结果:不逃逸、方法逃逸、线程逃逸。
- 不逃逸、方法逃逸:对象放到栈中(为了节约栈空间,还会做标量替换等操作,可参考《JIT实时编译特性》)。放到栈中的对象会随着方法结束而销毁,把不必放到堆中的对象放到了栈中。减轻了垃圾回收的压力。
- 线程逃逸:对象放到堆中。
下面举例说明:
//不逃逸 public static void main(String[] args) { String sb = createStringBuffer("a", "b"); sb.length(); } public static String createStringBuffer(String s1, String s2) { StringBuffer sb = new StringBuffer(); sb.append(s1); sb.append(s2); return sb.toString(); } //方法逃逸 public static void main(String[] args) { StringBuffer sb = createStringBuffer("a", "b"); sb.reverse(); } public static StringBuffer createStringBuffer(String s1, String s2) { StringBuffer sb = new StringBuffer(); sb.append(s1); sb.append(s2); return sb; } //线程逃逸 public static void main(String[] args) { StringBuffer sb = createStringBuffer("a", "b"); new Thread(() -> { sb.reverse(); }).start(); } public static StringBuffer createStringBuffer(String s1, String s2) { StringBuffer sb = new StringBuffer(); sb.append(s1); sb.append(s2); return sb; }
在Java代码运行时,通过JVM参数可指定是否开启逃逸分析,
-XX:+DoEscapeAnalysis : 表示开启逃逸分析
-XX:-DoEscapeAnalysis : 表示关闭逃逸分析 从jdk 1.7开始已经默认开始逃逸分析,如需关闭,需要指定-XX:-DoEscapeAnalysis
那么有关Java逃逸分析的介绍就到这里了,有问题欢迎在评论区留言讨论,我看到后也会回复的。
Tips:如果想看逃逸分析日志,可以添加java参数:-XX:+PrintEscapeAnalysis来打印。但是这个参数只有在debug版本的jdk版本有用。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?