广告
返回顶部
首页 > 资讯 > 后端开发 > Python >JVM内存增强之逃逸分析
  • 916
分享到

JVM内存增强之逃逸分析

2024-04-02 19:04:59 916人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

目录概念逃逸分析参数设计使用逃逸分析FAQ概念 逃逸分析一种数据分析算法,基于此算法可以有效减少 Java 对象在堆内存中的分配。 Hotspot 虚拟机的编译器能够分析出一个新对象

概念

逃逸分析一种数据分析算法,基于此算法可以有效减少 Java 对象在堆内存中的分配。 Hotspot 虚拟机的编译器能够分析出一个新对象的引用范围,然后决定是否要将这个对象分配到堆上.

 当一个对象在方法中被定义后,对象只在方法内部使用,则认为没有发生逃逸。

 当一个对象在方法中被定义后,它被外部方法所引用,则认为发生逃逸。

//对象发生了逃逸,不会在栈上分配,有可能导致GC STW
public StringBuffer append(String s1, String s2) {
 StringBuffer sb = new StringBuffer();
 sb.append(s1);
sb.append(s2);
 return sb;
}
//对象未发生逃逸
public String append(String s1, String s2) {
 StringBuffer sb = new StringBuffer();
 sb.append(s1);
 sb.append(s2);
 return sb.toString();
}

建议:开发中能在方法内部应用对象的,就尽量控制在内部

逃逸分析参数设计

jdk 1.7 版本之后, HotSpot 中默认就已经开启了逃逸分析,如果使用的是较早的

版本,开发人员则可以通过:

✓ 选项“ -XX:+DoEscapeAnalysis" 显式开启逃逸分析。

✓ 通过选项“ -XX:+PrintEscapeAnalysis" 查看逃逸分析的筛选结果。

使用逃逸分析

编译器可以对代码做如下优化

1.栈上分配:将堆分配转化为栈分配。如果一个对象在方法内创建,要使指向该对象的引用不会发生逃逸,对象可能是栈上分配的候选


public class ObjectStackAllocationTests {
 public static void main(String[] args) throws InterruptedException {
 long start = System.currentTimeMillis();
 for (int i = 0; i < 10000000; i++) {
 alloc();
 }
 long end = System.currentTimeMillis();
 System.out.println("花费的时间为: " + (end - start) + " ms");
 // 为了方便查看堆内存中对象个数,线程 sleep
 TimeUnit.MINUTES.sleep(5);
 }
 private static void alloc() {
 byte[] data = new byte[10];//未发生逃逸
 }
}

2.同步消除:

我们知道线程同步是靠牺牲性能来保证数据的正确性,这个过程的代价会非常高。程序 的并发行和性能都会降低。JVM 的 JIT 编译器可以借助逃逸分析来判断同步块所使用的锁对象是否只能够被一个线程应用?假如是,那么 JIT 编译器在编译这个同步块的时候就会取消对这部分代码上加的锁。这个取消同步的过程就叫同步省略,也叫锁消除

public class SynchronizedLockTest {
 public void lock() {
 Object obj= new Object();
 synchronized(obj) {
 System.out.println(obj);
 }
}

3.标量替换分析

所谓的标量(Scalar)一般指的是一个无法再分解成更小数据的数据。例如,Java 中 的原始数据类型就是标量。相对的,那些还可以分解的数据叫做聚合量(Aggregate),Java 中的对象就是聚合量,因为他可以分解成其他聚合量和标量。在 JIT 阶段,如果经过逃逸分析,发现一个对象不会被外界访问的话,那么经过 JIT 优化,就会把这个对象分解成若干个变量来代替。这个过程就是标量替换。

public class ObjectScalarReplaceTests {
 public static void main(String args[]) {
 long start = System.currentTimeMillis();
 for (int i = 0; i < 10000000; i++) {
 alloc();
 }
 long end = System.currentTimeMillis();
 System.out.println("花费的时间为: " + (end - start) + " ms");
 }
 private static void alloc() {
 Point point = new Point(1,2);
 }
 static class Point {
 private int x;
 private int y;
 public Point(int x,int y){
 this.x=x;
 this.y=y;
 }
 }
//对于上面代码,假如开启了标量替换,那么 alloc 方法的内容就会变为如下形式
private static void alloc() {
     int x=10;
     int y=20;
 }

alloc 方法内部的 Point 对象是一个聚合量,这个聚合量经过逃逸分析后,发现他并没有逃逸,就被替换成两个标量了。那么标量替换有什么好处呢?可以大大减少堆内存的占用。因为一旦不需要创建对象了,那么就不再需要分配堆内存了。标量替换为栈上分配 提供了很好的基础。 

FAQ

1.什么是逃逸分析?

可以有效减少 Java 对象在堆内存中的分配压力和同步负载的算法

2.逃逸分析有什么优势、劣势?

逃逸分析是需要消耗一定的性能去执行分析的,所以说如果方法中的对象全都是处于逃逸状态,那么就没有起到优化的作用,从而就白白损失了这部分的性能消耗

到此这篇关于JVM内存增强之逃逸分析的文章就介绍到这了,更多相关JVM逃逸内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: JVM内存增强之逃逸分析

本文链接: https://www.lsjlt.com/news/167800.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • JVM内存增强之逃逸分析
    目录概念逃逸分析参数设计使用逃逸分析FAQ概念 逃逸分析一种数据分析算法,基于此算法可以有效减少 Java 对象在堆内存中的分配。 Hotspot 虚拟机的编译器能够分析出一个新对象...
    99+
    2022-11-13
  • Golang学习之内存逃逸分析
    目录内存分配中的堆栈栈堆内存逃逸逃逸分析分析工具逃逸场景逃逸分析的作用在开始剖析Go逃逸分析前,我们要先清楚什么是堆栈。数据结构中有堆栈,内存分配中也有堆栈,两者在定义和用途上虽不同...
    99+
    2023-01-29
    Golang内存逃逸分析 Golang内存逃逸
  • ​golang面试题之内存逃逸的示例分析
    这篇文章将为大家详细讲解有关golang面试题之内存逃逸的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。问题知道golang的内存逃逸吗?什么情况下会发生内存逃逸?怎么答golang程序变量会携带...
    99+
    2023-06-14
  • Go语言中内存管理逃逸分析详解
    目录1. 前言2. 逃逸策略3. 逃逸场景3.1 指针逃逸3.2 栈空间不足逃逸3.3 动态类型逃逸3.4 闭包引用对象逃逸4.逃逸总结5. 注意事项1. 前言 所谓的逃逸分析(Es...
    99+
    2023-03-15
    Go 内存管理逃逸分析 Go 内存管理逃逸 Go 内存管理
  • JVM系列之内存模型的示例分析
    这篇文章主要介绍JVM系列之内存模型的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1. 内存模型和运行时数据区这一章学习java虚拟机内存模型(Java Virtual machine menory mod...
    99+
    2023-06-15
  • java应用开发之JVM运行时内存分析
    目录1.JVM的运行时内存也叫JVM堆2.JVM新创建的对象3.新生代详解4.老年代详解5.永久代1.JVM的运行时内存也叫JVM堆 从GC的角度可以将JVM分为新生代,老年代,永久...
    99+
    2022-11-12
  • JVM快速调优手册v1.0之四:堆内存分配的CMS公式解析
         一.JVM 堆内存组成 Java堆由Perm区和Heap区组成,Heap区由Old区和New区(也叫Young区)组成,New区由Eden区、From区和To区(Survivor)组成。 ...
    99+
    2023-06-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作