JVM内存模型深度剖析与优化

欢迎大家关注我的微信公众号:
欢迎大家关注我的微信公众号

目录

JVM整体结构及内存模型

JVM内存参数设置 


JVM整体结构及内存模型

首先附一段简单代码,我们从代码层面来讲解内存模型 

public class Math {public static final int initData = 666;public static User user = new User();public int compute() {  //一个方法对应一块栈帧内存区域int a = 1;int b = 2;int c = (a + b) * 10;return c;}public static void main(String[] args) {Math math = new Math();math.compute();System.out.println("test");}}

JVM内存模型图

0

 以JDK8为例,JVM虚拟机内存分为堆内存、栈内存、方法区(元空间)、本地方法栈及程序计数器

栈内存(线程) 

        每开启一个线程,栈内存都会为每个线程分配一块区域,线程中每个方法对应一块栈帧内存区域。main方法是一个栈帧,main方法中调用了computer()方法,因此computer()也是一个栈帧。根据先进后出原则,每一个栈帧都按顺序从下至上排列。每个栈帧内存区域都包括局部变量表、操作数栈、动态链接及方法出口。

        栈和局部变量通过JVM指令会进行一些操作。执行int a = 1:首先将常量压入栈。jvm指令iconst_1将int类型常量1压入操作数栈。然后将栈中的值存入局部变量。指令istore_1 将int类型值存入局部变量1。此时局部变量表中a=1。执行int b = 2:iconst_2将int类型常量2压入操作数栈istore_2 将int类型值存入局部变量2。此时局部变量表中b=2。执行int c = (a + b) * 10:iload_1 从局部变量1中装载int类型值1,iload_2 从局部变量2中装载int类型值2,放入操作数栈,iadd 执行int类型的加法1+2=3。然后bipush 将一个8位带符号整数压入栈,也就是将10压入操作数栈。之后imul 执行int类型的乘法,即3*10=30,将结果30重新压入操作数栈。istore_3 将int类型值存入局部变量3,局表变量表中为int c = 30。iload_3从局部变量3中装载int类型值3,放入操作数栈,将30重新压回操作数栈,最后ireturn 从方法中返回int类型的数据,即执行return c

         动态链接:math.compute()方法调用,其实就在常量池中的一个个常量。当代码执行到该方法时,需要解析符号,在方法区里去找寻对应的符号的直接内存地址。

        方法出口:当执行完compute()方法之后,需要回到主线程里继续执行下面的代码。那回到什么位置,执行哪行代码,这些信息都存在方法出口里,来找到继续执行的位置。

注意:main()方法里创建了一个math对象,我们知道对象一般是放在堆内存里的,那么此时main栈帧里的局部变量表,对应的math内存区域存放的就是堆内存中Math对象的内存地址。因此栈内存跟堆内存的关系也表示栈内存里会存放很多堆内存里的内存地址。 

程序计数器 

        程序计数器用于计算jvm的操作步骤,每操作一次计数器+1,相当于索引来找到对应的操作内容,执行对应的指令。

方法区(元空间)

        元空间存放的是常量、静态变量、类元信息等。 当代码load到内存中时,会解析为运行时常量池,之后会详细解释,文本不在这里展开叙述。

本地方法栈

        java很多方法都是执行本地方法,比如new Thread().start(),这里的start()就是调用本地方法,他的底层是由C或C++来实现的。本地方法栈就是为这些本地方法来分配内存空间。

堆内存 

        堆内存主要分为年轻代和老年代,分配比例一般为1:2。年轻代又分为伊甸园区和幸存区(S0与S1),分配比例一般为8:1:1。我们新创建的对象一般存放在伊甸园区。当伊甸园区内存放满时,触发Young GC(Minor GC),将不再被其他对象所引用的对象进行销毁,而仍然有用的对象会放入S0区,并随着young gc不断回收,幸存的对象会不断在S0与S1之间来回存放,并且每幸存一次,生存年龄+1。当幸存对象生存年龄达到15时,会存入老年代。若老年代也满了,那么这个时候将产生FullGC(MajorGC),进行老年代的内存清理。若老年代执行了Full GC之后发现依然无法进行对象的保存,就会产生OOM异常“OutOfMemoryError”。

JVM内存参数设置 

0

 Spring Boot程序的JVM参数设置格式(Tomcat启动直接加在bin目录下catalina.sh文件里):

java -Xms2048M -Xmx2048M -Xmn1024M -Xss512K -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -jar microservice-eureka-server.jar -Xss:每个线程的栈大小

-Xss:每个线程的栈大小

-Xms:设置堆的初始可用大小,默认物理内存的1/64

-Xmx:设置堆的最大可用大小,默认物理内存的1/4

-Xmn:新生代大小

-XX:NewRatio:默认2表示新生代占年老代的1/2,占整个堆内存的1/3。

-XX:SurvivorRatio:默认8表示一个survivor区占用1/8的Eden内存,即1/10的新生代内存。

关于元空间的JVM参数有两个:-XX:MetaspaceSize=N和 -XX:MaxMetaspaceSize=N

-XX:MaxMetaspaceSize: 设置元空间最大值, 默认是-1, 即不限制, 或者说只受限于本地内存大小。

-XX:MetaspaceSize: 指定元空间触发Fullgc的初始阈值(元空间无固定初始大小), 以字节为单位,默认是21M左右,达到该值就会触发full gc进行类型卸载, 同时收集器会对该值进行调整: 如果释放了大量的空间, 就适当降低该值; 如果释放了很少的空间, 那么在不超过-XX:MaxMetaspaceSize(如果设置了的话) 的情况下, 适当提高该值。这个跟早期jdk版本的-XX:PermSize参数意思不一样,-XX:PermSize代表永久代的初始容量。

由于调整元空间的大小需要Full GC,这是非常昂贵的操作,如果应用在启动的时候发生大量Full GC,通常都是由于永久代或元空间发生了大小调整,基于这种情况,一般建议在JVM参数中将MetaspaceSize和MaxMetaspaceSize设置成一样的值,并设置得比初始值要大,对于8G物理内存的机器来说,一般我会将这两个值都设置为256M。

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

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

相关文章

性能测试分析案例-定位DNS解析很慢

环境准备 预先安装 docker 等工具,如 apt install docker.io。 操作和解析 执行下面的命令,拉取案例中使用的 Docker 镜像: docker pull feisky/dnsutils运行下面的命令,查看主机当前配置的 DNS 服务器: cat /etc…

你知道谁才是 “最懂程序员” 的搜索引擎?

大家好,我是奇兵,作为一名程序员,我们开发的过程中几乎每天都和搜索引擎打交道,利用它来搜文档、解决 Bug 等等。 而随着 AI 的发展,搜索引擎也变得越来越智能,市面上也涌现除了越来越多的 AI 搜索引擎。 …

【qt】sdk写pro写法,cv,onnx,cudnn

我的sdk在OpenCV003项目里: pro中添加 CONFIG(release, debug|release) {LIBS -L$$PWD/sdk/onnxruntime-x64-gpu/lib/ -lonnxruntimeLIBS -L$$PWD/sdk/onnxruntime-x64-gpu/lib/ -lonnxruntime_providers_cudaLIBS -L$$PWD/sdk/onnxruntime-x64-gpu/lib/ -lon…

深入探索JavaScript中实用而高级的Rest参数和Spread语法

🧑‍🎓 个人主页:《爱蹦跶的大A阿》 🔥当前正在更新专栏:《VUE》 、《JavaScript保姆级教程》、《krpano》、《krpano中文文档》 ​ ​ ✨ 前言 函数是JavaScript这个语言的核心,而如何处理函数的参数是函数编程中非…

深度学习工具-Amazon SageMaker使用

Amazon SageMaker 深度学习程序可能需要很多计算资源,这很容易超出你的本地计算机所能提供的范围。云计算服务允许你使用功能更强大的计算机更轻松地运行本书的GPU密集型代码。 注册 首先,我们需要在注册一个帐户https://aws.amazon.com/。 为了增加安…

io.lettuce.core.RedisCommandExecutionException: NOAUTH Authentication required.

报错信息: 浏览器中的报错信息 IDEA中的报错信息 报错原因: SpringBoot整合Redis使用的默认配置,但是我们设置了Redis的密码,而默认配置中密码是为空的,导致不能够连接 浏览器中的报错信息 There was an unexpected …

ChatGLM2-6B 大语言模型本地搭建

ChatGLM模型介绍: ChatGLM2-6B 是清华 NLP 团队于不久前发布的中英双语对话模型,它具备了强大的问答和对话功能。拥有最大32K上下文,并且在授权后可免费商用! ChatGLM2-6B的6B代表了训练参数量为60亿,同时运用了模型…

Mac/Linux虚拟机CrossOver2024新版下载使用教程

CrossOver不像Parallels或VMware的模拟器,而是实实在在Mac OS X系统上运行的一个软件,该软件可以让用户在mac是上直接运行windows软件,本文为大家带来的是CrossOver Mac版安装教程! CrossOver Mac-安装包下载如下:http…

zookerper入门

zookerper介绍 ZooKeeper 是一个开源的分布式协调框架,主要用来解决分布式集群中应用系统的一致性问题. ZooKeeper本质上是一个分布式的小文件存储系统(Zookeeper文件系统监听机制).提供基于类似于文件系统的目录树方式的数据存储,并且可以…

typora导出html添加目录

typora导出html添加目录 使用方法 首先要从typora导出html文件,之后用记事本编辑器html文件 找到文档最后面,如图: 用文字编辑类工具打开sideBar.txt,复制其中所有内容【内容在下面】 在如上图的位置插入所复制的内容 打开修改…

漏油控制器有用吗?漏油监测器多少钱一个?

漏油控制器也可以被称作漏油监测器、漏油传感器,是漏油检测系统里的一部分,一般是和漏油检测绳组合在一起使用,用来检测油罐、输油管道、油类化工厂等场合是否有油料泄露。很多人刚开始可能会觉得难以置信,这么一个小东西就可以检…

SPDK中常用的性能测试工具

本文主要介绍磁盘性能评估的方法,针对用户态驱动Kernel与SPDK中各种IO测试工具的使用方法做出总结。其中fio是一个常用的IO测试工具,可以运行在Linux、Windows等多种系统之上,可以用来测试本地磁盘、网络存储等的性能。为了和SPDK的fio工具相…

两周掌握Vue3(四):计算属性、监听属性、事件处理

文章目录 一、计算属性1.什么是计算属性2.代码示例 二、监听属性三、事件处理 代码仓库:跳转 当前分支:04 一、计算属性 1.什么是计算属性 Vue 中的计算属性具有以下作用: 数据处理:计算属性可以用于对数据进行处理和计算&…

格雷希尔G65系列快速接头满足汽车减震器的气压、油压测试要求

当汽车经过不平路面时,汽车减震器可以抑制弹簧吸震后因反弹带来的震荡和来自路面的冲击,为乘客带来平稳舒适的行车体验。减震器在出厂之前,需要模拟汽车的真实行驶环境,在模拟当中需要对它们进行气压和油压的轮番测试。 客户的测试…

ssm基于java web的防疫工作志愿者服务平台的设计与实现论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本防疫工作志愿者服务平台就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数…

PHP短链接url还原成长链接

在开发过程中,碰到了需要校验用户回填的短链接是不是系统所需要的,于是就需要还原找出短链接所对应的长链接。 长链接转短链接 在百度上搜索程序员,跳转页面后的url就是一个长链接。当然你可以从任何地方复制一个长链接过来。 长链接 http…

stm32---输入捕获实验实操(巨详细)

这次来分享上次没说完的输入捕获的知识点 实验中用到两个引脚,一个是通用定时器 TIM3 的通道 1,即 PA6,用于输出 PWM 信号,另一 个是高级控制定时器 TIM1 的通道 1,即 PA8,用于 PWM 输入捕获,实…

vue3 生命周期

与 2.x 版本生命周期相对应的组合式 API beforeCreate -> 使用 setup() created -> 使用 setup() beforeMount -> onBeforeMount mounted -> onMounted beforeUpdate -> onBeforeUpdate updated -> onUpdated beforeDestroy -> onBeforeUnmount destroye…

window中安装Apache http server(httpd-2.4.58-win64-VS17)

windows中安装Apache http server(httpd-2.4.58-win64-VS17) 1、下载windows版本的的httpd, https://httpd.apache.org/docs/current/platform/windows.html#down 这里选择的是Apache Lounge编译的版本 https://www.apachelounge.com/download/ 2、解压到指定目录,这…

如何修复DLL错误或丢失的问题,这里提供几种方法

DLL错误是指DLL文件的任何错误,一种以.dll文件扩展名结尾的文件。 DLL错误可能出现在微软的任何操作系统中,包括Windows 10、Windows 8、Windows 7、Windows Vista和Windows XP。 DLL错误尤其麻烦,因为存在许多这样类型的文件,所…