JVM之内存分配的详细解析

news2024/12/24 20:45:53

内存分配

两种方式

不分配内存的对象无法进行其他操作,JVM 为对象分配内存的过程:首先计算对象占用空间大小,接着在堆中划分一块内存给新对象

  • 如果内存规整,使用指针碰撞(Bump The Pointer)。所有用过的内存在一边,空闲的内存在另外一边,中间有一个指针作为分界点的指示器,分配内存就仅仅是把指针向空闲那边挪动一段与对象大小相等的距离

  • 如果内存不规整,虚拟机需要维护一个空闲列表(Free List)分配。已使用的内存和未使用的内存相互交错,虚拟机维护了一个列表,记录上哪些内存块是可用的,再分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的内容

TLAB

TLAB:Thread Local Allocation Buffer,为每个线程在堆内单独分配了一个缓冲区,多线程分配内存时,使用 TLAB 可以避免线程安全问题,同时还能够提升内存分配的吞吐量,这种内存分配方式叫做快速分配策略

  • 栈上分配使用的是栈来进行对象内存的分配

  • TLAB 分配使用的是 Eden 区域进行内存分配,属于堆内存

堆区是线程共享区域,任何线程都可以访问到堆区中的共享数据,由于对象实例的创建在 JVM 中非常频繁,因此在并发环境下为避免多个线程操作同一地址,需要使用加锁等机制,进而影响分配速度

问题:堆空间都是共享的么? 不一定,因为还有 TLAB,在堆中划分出一块区域,为每个线程所独占

JVM 是将 TLAB 作为内存分配的首选,但不是所有的对象实例都能够在 TLAB 中成功分配内存,一旦对象在 TLAB 空间分配内存失败时,JVM 就会通过使用加锁机制确保数据操作的原子性,从而直接在堆中分配内存

栈上分配优先于 TLAB 分配进行,逃逸分析中若可进行栈上分配优化,会优先进行对象栈上直接分配内存

参数设置:

  • -XX:UseTLAB:设置是否开启 TLAB 空间

  • -XX:TLABWasteTargetPercent:设置 TLAB 空间所占用 Eden 空间的百分比大小,默认情况下 TLAB 空间的内存非常小,仅占有整个 Eden 空间的1%

  • -XX:TLABRefillWasteFraction:指当 TLAB 空间不足,请求分配的对象内存大小超过此阈值时不会进行 TLAB 分配,直接进行堆内存分配,否则还是会优先进行 TLAB 分配

逃逸分析

即时编译(Just-in-time Compilation,JIT)是一种通过在运行时将字节码翻译为机器码,从而改善性能的技术,在 HotSpot 实现中有多种选择:C1、C2 和 C1+C2,分别对应 Client、Server 和分层编译

  • C1 编译速度快,优化方式比较保守;C2 编译速度慢,优化方式比较激进

  • C1+C2 在开始阶段采用 C1 编译,当代码运行到一定热度之后采用 C2 重新编译

逃逸分析并不是直接的优化手段,而是一个代码分析方式,通过动态分析对象的作用域,为优化手段如栈上分配、标量替换和同步消除等提供依据,发生逃逸行为的情况有两种:方法逃逸和线程逃逸

  • 方法逃逸:当一个对象在方法中定义之后,被外部方法引用

    • 全局逃逸:一个对象的作用范围逃出了当前方法或者当前线程,比如对象是一个静态变量、全局变量赋值、已经发生逃逸的对象、作为当前方法的返回值

    • 参数逃逸:一个对象被作为方法参数传递或者被参数引用

  • 线程逃逸:如类变量或实例变量,可能被其它线程访问到

如果不存在逃逸行为,则可以对该对象进行如下优化:同步消除、标量替换和栈上分配

  • 同步消除

    线程同步本身比较耗时,如果确定一个对象不会逃逸出线程,不被其它线程访问到,那对象的读写就不会存在竞争,则可以消除对该对象的同步锁,通过 -XX:+EliminateLocks 可以开启同步消除 ( - 号关闭)

  • 标量替换

    • 标量替换:如果把一个对象拆散,将其成员变量恢复到基本类型来访问

    • 标量 (scalar) :不可分割的量,如基本数据类型和 reference 类型

      聚合量 (Aggregate):一个数据可以继续分解,对象一般是聚合量

    • 如果逃逸分析发现一个对象不会被外部访问,并且该对象可以被拆散,那么经过优化之后,并不直接生成该对象,而是将该对象成员变量分解若干个被这个方法使用的成员变量所代替

    • 参数设置:

      • -XX:+EliminateAllocations:开启标量替换

      • -XX:+PrintEliminateAllocations:查看标量替换情况

  • 栈上分配

    JIT 编译器在编译期间根据逃逸分析的结果,如果一个对象没有逃逸出方法的话,就可能被优化成栈上分配。分配完成后,继续在调用栈内执行,最后线程结束,栈空间被回收,局部变量对象也被回收,这样就无需 GC

    User 对象的作用域局限在方法 fn 中,可以使用标量替换的优化手段在栈上分配对象的成员变量,这样就不会生成 User 对象,大大减轻 GC 的压力

    public class JVM {
        public static void main(String[] args) throws Exception {
            int sum = 0;
            int count = 1000000;
            //warm up
            for (int i = 0; i < count ; i++) {
                sum += fn(i);
            }
            System.out.println(sum);
            System.in.read();
        }
        private static int fn(int age) {
            User user = new User(age);
            int i = user.getAge();
            return i;
        }
    }
    ​
    class User {
        private final int age;
    ​
        public User(int age) {
            this.age = age;
        }
    ​
        public int getAge() {
            return age;
        }
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1646788.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

快速入门!学习鸿蒙App开发的终极指南!

鸿蒙&#xff08;HarmonyOS&#xff09;是华为推出的一款分布式操作系统&#xff0c;旨在为不同设备提供统一的操作体验。鸿蒙App开发可以让应用程序在多个设备上实现流畅运行。本文将介绍鸿蒙App开发的终极指南&#xff0c;帮助您快速入门。 开发环境搭建 鸿蒙App开发过程需要…

R语言Rstudio突然无法启动?如何解决

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

fiscobcos 3.x linux安装与java简单调用

所用环境 vmware 16 Pro centos7.6 jdk11.0.6 ideal 2022 1、安装fiscobcos # 创建操作目录 # cd ~ && mkdir -p fisco && cd fisco# 下载建链脚本 # curl -#LO https://github.com/FISCO-BCOS/FISCO-BCOS/releases/download/v3.6.0/build_chain.sh &a…

知识图谱在提升大语言模型性能中的应用:减少幻觉与增强推理的综述

幻觉现象指的是模型在生成文本时可能会产生一些听起来合理但实际上并不准确或相关的输出&#xff0c;这主要是由于模型在训练数据中存在知识盲区所致。 为了解决这一问题&#xff0c;研究人员采取了多种策略&#xff0c;其中包括利用知识图谱作为外部信息源。知识图谱通过将信息…

Kalign 3:大型数据集的多序列比对

之前一直用的是muscle&#xff0c;看到一个文章使用了Kalign&#xff0c;尝试一下吧 安装 wget -c https://github.com/TimoLassmann/kalign/archive/refs/tags/v3.4.0.tar.gz tar -zxvf v3.4.0.tar.gz cd kalign-3.4.0 mkdir build cd build cmake .. make make test su…

OpenNJet:云原生技术中的创新者与实践者

目录 引言OpenNJet介绍OpenNJet优势1. 性能无损动态配置2. 灵活的CoPilot框架3. 支持HTTP/34. 支持国密5. 企业级应用6. 高效安全 OpenNJet 编译与安装环境准备编译环境配置配置yum源yum 安装软件包创建符号连接修改 ld.so.conf 配置 编译代码 部署 WEB SERVER配置OpenNJet部署…

Unity 性能优化之遮挡剔除(Occlusion Culling)(六)

提示&#xff1a;仅供参考&#xff0c;有误之处&#xff0c;麻烦大佬指出&#xff0c;不胜感激&#xff01; 文章目录 前言一、遮挡剔除是什么&#xff1f;二、静态遮挡剔除的使用步骤1.标记为遮挡剔除对象2.创建Occlusion Area组件3.烘焙4.Occlusion窗口Bake的参数Smallest Oc…

linux实验(数据库备份)

以下所有操作皆以机房电脑上的虚拟机为基础环境 下载链接&#xff1a;Linux课程机房虚拟机# 切换到root用户 su - root安装数据库mysql 5.7 rpm -ivh https://mirrors4.tuna.tsinghua.edu.cn/mysql/yum/mysql-5.7-community-el7-x86_64/mysql-community-common-5.7.29-1.el7.x…

ROS 2边学边练(43)-- 利用GTest写一个基本测试(C++)

前言 在ROS&#xff08;Robot Operating System&#xff09;中&#xff0c;gtest&#xff08;Google Test&#xff09;是一个广泛使用的C测试框架&#xff0c;用于编写和执行单元测试。这些测试可以验证ROS节点、服务和消息等的正确性和性能。 如果我们需要在写的包中添加测试&…

严苛工作环境下IMU的最佳选择—爱普生M-G364及M-G354

爱普生(EPSON)秉持其省、小、精的核心技术&#xff0c;并运用长期于工业市场中所累积的专业经验与知识&#xff0c;专注于研发符合市场需求的IMU产品&#xff0c;打造出即使在具高挑战性的严苛环境下&#xff0c;亦可提供优异稳定性及高分辨率的IMU产品。随着自主精密农业机械、…

echars设置渐变颜色的方法

在我们日常的开发中&#xff0c;难免会遇到有需求&#xff0c;需要使用echars设置渐变的图表&#xff0c;如果我们需要设置给图表设置渐变颜色的话&#xff0c;我们只需要在 series 配置项中 添加相应的属性配置项即可。 方式一&#xff1a;colorStops type&#xff1a;‘lin…

jenkins常用插件之Filesystem Trigger

安装插件 Filesystem Trigger 项目配置 验证 根据上述配置&#xff0c;当1.txt文件发生变化时&#xff0c;jenkins每分钟会进行检测&#xff0c;检测到后即进行任务构建&#xff0c;后续的具体操作可自行配置

C++ 如何进阶?

一、C基础&#xff08;3个月&#xff09; 1、面向对象的三大特性&#xff1a;封装、继承、多态 2、类的访问权限&#xff1a;private、protected、public 3、类的构造函数、析构函数、赋值函数、拷贝函数 4、移动构造函数与接贝构造函数对比 5、深接贝与浅贝的区别 6、空…

为什么相同内核的Linux桌面稳定干净,而Android却臃肿不堪?

在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「 Linux的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01; 对于这个问题&#xff0c;我…

每日一题 盛最多水的容器

. - 力扣&#xff08;LeetCode&#xff09; 思路分析: 利用函数的单调性解决这道题两端取最小&#xff0c;最小的往里找就是高不变或者缩小 宽减少 一定是减小的因此这题可以使用左右指针实现 public int maxArea(int[] height) {int left 0;int right height.length - 1;i…

红日靶场ATTCK 1通关攻略

环境 拓扑图 VM1 web服务器 win7&#xff08;192.168.22.129&#xff0c;10.10.10.140&#xff09; VM2 win2003&#xff08;10.10.10.135&#xff09; VM3 DC win2008&#xff08;10.10.10.138&#xff09; 环境搭建 win7&#xff1a; 设置内网两张网卡&#xff0c;开启…

TC3xx MTU概述(2)

目录 1.概述 2.如何配置NDT 3.小结 1.概述 上篇TC3xx MTU概述(1)-CSDN博客我们讲解了MTU基本功能和MBIST基本概念&#xff0c;接下来我们继续讲解MTU如何配置NDT算法。 2.如何配置NDT 前面聊了那么多概念&#xff0c;我们还是来看看如何配置MTU来实现NDT。 MTU寄存器分为…

为什么需要自动化测试?自动化有哪些优势?

前言 自动化测试&#xff0c;最近些年可谓是大火。招聘上的要求也好&#xff0c;培训班的广告也罢&#xff0c;比比皆是&#xff0c;足以说明它在业内的火爆程度。 虽然说会写自动化测试并不能说明你就很牛批&#xff0c;但是你不会的话&#xff0c;那么很抱歉&#xff0c;你…

如何复制本地docker镜像到其他主机

&#xff08;1&#xff09;打包镜像 比如我要复制的镜像是grafana的镜像 docker images 这里我把打包的镜像放在了根~目录下&#xff0c;如截图所示&#xff1a; docker save grafana/grafana:latest -o ~/grafana.jar &#xff08;2&#xff09;移动镜像 scp命令拷贝镜像到目标…

C语言 循环控制流程的跳转语句

本文 我们来说 控制流程的跳转语句 C语言 提供三种 控制流程的跳转语句 1. break 语句 我们之前讲 switch 时 大家已经看到过这个 break 了 作用是跳出当前 switch 在循环中 它的作用也差不多 这里 我们举个生活中的例子 例如 我们在操场上跑步 计划跑十圈 但是 还没跑完 我…