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

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

Java语言的跨平台性

Java语言的跨平台特性.png

  • 问题: Java语言的跨平台性是如何做到的
    • 通过不同操作系统平台的JVM版本,Linux和Windows的JVM版本各不相同
    • Java是跨平台解释性语言,可以在不同的操作系统运行,JVM从软件层面屏蔽不同操作系统在底层硬件和指令的差别

JVM内存模型

详细链接: https://www.processon.com/view/link/61e31579f346fb06cb9afec9

JVM内存模型.png

  • JVM的组成部分主要分为两个子系统和两个组件
    • 两个子系统 就是 类加载子系统 和 字节码执行引擎
      • 类加载子系统 主要是负责将字节码文件加载到JVM内存中去
      • 字节码执行引擎 主要是负责GC、执行字节码文件中的指令以及修改程序计数器中的值等
    • 两个组件 就是 本地接口 和 运行时数据区
      • 本地接口 主要是与本地库打交道,都知道JVM是C++写的,所以需要一些本地库的支持
      • 运行时数据区 就是我们常说的JVM内存,主要分为线程共享和线程独享两大块
        • 线程共享 有 堆 和 方法区
            • 一般new出来的对象都会存放在堆中
          • 方法区(元空间)
            • 方法区在JDK 7时处于堆中,在JDK 8中,方法区叫元空间,从堆中移除而放到直接内存中,主要是因为直接内存对IO操作具有更高的性能并且减少中间步骤的开销(虚拟内存到直接内存的重复开销)
        • 线程独享 有 栈、本地方法栈 和程序计数器
            • 栈主要是存放栈帧的,一个方法对应一个栈帧,栈帧主要分为局部变量表、操作数栈、方法出口、动态链接
              • 局部变量表
                • 局部变量表 类似于一个table,存放编译期间的变量或对象的内存地址
                  • 在编译期间,this会作为隐式参数放在局部变量表的第一位
              • 操作数栈
                • 操作数栈 主要是用来进行一些操作数运算,运算完之后再赋值到局部变量表
              • 方法出口
                • 方法出口 就是通过它进行定位方法被调用的位置
              • 动态链接
                • 动态链接 就是引用类型变量与堆中实际对象的关联关系,主要是用来定位堆中实际对象的
          • 本地方法栈 与 栈基本一致,只不过是用来处理本地方法
          • 程序计数器 相当于代码执行位置的标识
  • 整体流程就是 类加载子系统会将字节码文件加载到JVM内存中,而字节码文件不能直接被操作系统识别,所以需要通过字节码执行引擎去解析成操作系统能识别的指令,然后将指令交给CPU去执行,而这个过程需要本地接口与本地库的交互

JVM参数设置

JVM内存参数设置.png

  • 分析: 方法区如果内存使用达到21M(默认21M),也会触发FullGC,FullGC不但会回收堆也会回收方法区

  • 推荐: JVM调参

    java -Xms2048M -Xmx2048M -Xmn1024M -Xss512K -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -jar a.jar
    
  • 方法区的参数

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

    • -Xms: 堆空间初始大小
    • -Xmx: 堆最大空间
    • -Xmn: 年轻代大小
    • -Xss: 栈空间大小
    • -XX:NewRatio: 默认2表示年轻代占老年代的1/2,占堆的1/3
    • -XX:SurvivorRatio: 默认8表示一个Survivor区占Eden区的1/8,占堆的1/10
  • 调优: 在设置JVM参数时,建议将方法区也设置一个值比如256M,避免在项目启动时,因为方法区太小而导致频繁FullGC

常见问题

什么样的对象会被移动到老年代

  • 长期存活的对象,比如静态变量引用对象、对象池、缓存对象、Spring容器中的Bean对象等

MinorGC和FullGC都会触发STW吗

  • 都会,但MinorGC触发STW时间比较短,用户几乎无感知,但FullGC触发时间比较长

为什么要设置STW机制

  • 什么是STW

    • STW就是Stop The World,停止所有用户线程。字节码执行引擎会开启后台线程去进行垃圾回收,就比如电商系统,用户发起下单请求对应的后端会有用户线程进行处理,而相对应的会产生大量的对象,需要及时的进行垃圾回收,这时候会进行STW,对于用户的体验就是卡顿一下,如果STW时间过长对于用户的体验是非常不好的
  • 当通过gcroots去找可回收的对象时,假如当前确认A对象此时没有被引用着,如果不停止所有用户线程,可能会出现有其他线程再次引用A对象,但gcroots不知道A对象又被引用了,可能就直接把该对象回收掉了,造成这条引用断裂,这样会出大问题,为了避免这种情况的产生,JVM干脆停止所有用户线程去进行回收

  • 可以举个例子,在使用serial和parNew进行垃圾回收时,因为采用的是复制算法,如果不暂停所有用户线程,那么复制到Survivor区可能有存活的对象和垃圾对象,这样肯定是不行的

什么时候会报错StackOverflowError

  • 比如当递归调用方法的时候很有可能出现该错误,因为线程栈被栈帧放满
  • -Xss设置越小,说明一个线程栈里能分配的栈帧也就越小,但是对JVM整体来说能开启的线程数也就越多,为什么这么说呢
    • 因为方法区和栈都是直接使用操作系统的直接内存的,栈内存越小,理论上操作系统就能开更多的线程

JVM优化原则是什么

  • 尽可能让对象都在年轻代里被分配和回收,尽量别让太多对象频繁进入老年代,避免频繁对老年代进行垃圾回收,同时给系统充足的内存大小,避免年轻代频繁的进行垃圾回收

解释下Java里面的直接内存

  • 直接内存有一种叫法堆外内存
  • 直接内存指的是Java应用程序直接从操作系统申请到的内存,运行时数据区的内存都是虚拟的内存

为什么JDK8将方法区从堆上移动到堆外内存

  • 因为直接使用直接内存,IO操作上具有更高的性能,跟零拷贝的原理有点雷同

有哪些方式可以直接使用直接内存

  • Java的Unsafe类,做了一些本地内存的操作
  • Netty的直接内存(Direct Memory),底层会调用操作系统的malloc函数
  • JNI或者JNA程序,直接操纵了本地内存,比如一些加密库

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

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

相关文章

JOSEF约瑟 JZS-7G-42 AC220V静态可调延时中间继电器 端子式导轨安装15ms-10s

系列型号:JZS-7G-57端子排延时中间继电器;JZS-7G-42X端子排延时中间继电器;JZS-7G-22X端子排延时中间继电器;JZS-7G-21端子排延时中间继电器;JZS-7G-41端子排延时中间继电器;JZS-7G-51端子排延时中间继电器…

大数据可视化python01

import pandas as pd import matplotlib.pyplot as plt# 设置中文改写字体 plt.rcParams[font.sans-serif] [SimHei]# 读取数据 data pd.read_csv(C:/Users/wzf/Desktop/读取数据进行数据可视化练习/实训作业练习/瓜果类单位面积产量.csv ,encoding utf-8)#输出 print(data)…

Docker Swarm全解析:实现微服务高可用与故障转移的秘密武器

🐇明明跟你说过:个人主页 🏅个人专栏:《Docker入门到精通》 《k8s入门到实战》🏅 🔖行路有良友,便是天堂🔖 目录 一、基本概念和介绍 1、Docker Swarm 是什么,它与 …

#stm学习总结 (二十八)硬件随机数实验

28.1 随机数发生器简介 STM32F407 自带了硬件随机数发生器(RNG),RNG 处理器是一个以连续模拟噪声为基础的随机数发生器,在主机读数时提供一个 32 位的随机数。 28.1.1 RNG 框图 STM32F407 的随机数发生器(RNG&#x…

3dmax corona渲染器和vray渲染器哪个好?

Corona和Vray这两个渲染器都很不错,每个都有自己的优点和适用的情况,所以很难说哪个更好。 下面我简单给你对比一下: 1、操作界面:Vray的界面比较多,参数设置也复杂一点,初学者可能会觉得有点难上手。但C…

【cmu15445c++入门】(13)C++的std::promise

一、说明 std::promise 是C11并发编程中常用的一个类&#xff0c;常配合std::future使用。其作用是在一个线程t1中保存一个类型typename T的值&#xff0c;可供相绑定的std::future对象在另一线程t2中获取 二、代码 #include <chrono> #include <future> #includ…

零基础自学C语言|数据在内存中的存储

✈整数在内存中的存储 在讲解操作符的时候&#xff0c;我们就讲过了下面的内容&#xff1a; 整数的2进制表示方法有三种&#xff0c;即原码、反码和补码 三种表示方法均有符号位和数值位两部分&#xff0c;符号位都是用0表示"正"&#xff0c;用1表示"负"&…

【前端素材】推荐优质后台管理系统 Adminity平台模板(附源码)

一、需求分析 1、系统定义 后台管理系统是一种用于管理网站、应用程序或系统的管理界面&#xff0c;通常由管理员和工作人员使用。它提供了访问和控制网站或应用程序后台功能的工具和界面&#xff0c;使其能够管理用户、内容、数据和其他各种功能。 2、功能需求 后台管理系…

你用多久拿下了PMP(项目管理专业人士资格认证)?

大概1个月左右&#xff0c;一般的2个月左右也差不多了。 PMP考试现在是第七版的教材&#xff0c;跟考纲了&#xff0c;相对第六版的来说增加了很多敏捷题型&#xff0c;相对要灵活很多&#xff0c;难度也有所提升&#xff0c;我的备考经历给大家参考下&#xff0c;希望对你有帮…

移动互联网时代的APP上架流程和要点

摘要 本文将介绍移动应用程序上架的基本流程和要点&#xff0c;包括应用商店注册、APP材料准备、打包上传App、APP审核以及发布APP的详细步骤。此外&#xff0c;还会提到利用appuploder工具简化iOS应用上架步骤的方法&#xff0c; 引言 在移动互联网时代&#xff0c;开发一…

Python WikiGPT代码,GPT代码实战,逐行讲解GPT代码,教你完整写完GPT代码,GPT代码模板,一文教你学会写GPT代码

1.GPT基本介绍 在GPT1诞生之前&#xff0c;NLP领域已存在多种任务&#xff0c;比如文本分类、语义相似度&#xff0c;以及问答等&#xff0c;这些任务的共同点在于它们都是有监督学习&#xff0c;且各自维护不同的量级较小的训练语料。OpenAI为了进一步提升这些任务的预测效果&…

数据可视化基础与应用-02-基于powerbi实现连锁糕点店数据集的仪表盘制作

总结 本系列是数据可视化基础与应用的第02篇&#xff0c;主要介绍基于powerbi实现一个连锁糕点店数据集的仪表盘制作。 数据集描述 有一个数据集&#xff0c;包含四张工作簿&#xff0c;每个工作簿是一张表&#xff0c;其中可以销售表可以划分为事实表&#xff0c;产品表&am…