当前位置: 首页 > news >正文

JVM加强

目录

JVM运行时的数据区(内存结构):

线程独享:

线程共享:

什么时候会内存溢出

JVM有哪些垃圾回收算法

GC如何判断对象可以被回收

典型的垃圾回收器

CMS:

G1:

类加载器和双亲委派机制:

类加载器

双亲委派机制

JVM中有哪些引用

虚引用

类加载的过程

JVM类初始化的顺序

对象的创建过程

对象头中有哪些信息

JVM的内存参数

GC的回收机制与原理


JVM运行时的数据区(内存结构):

线程独享:

  • 虚拟机栈:每次调用方法时都会在虚拟机栈中产生一个栈帧,每个栈帧中都有方法对应的参数、局部变量、方法出口等信息,方法执行完毕后释放栈帧。
  • 本地方法栈:为native修饰的本地方法提供的空间,在HotSpot中与虚拟机合二为一。
  • 程序计数器:保存指令执行的地址,方便线程切回后能够继续执行代码

线程共享:

  • 堆内存:jvm进行垃圾回收的主要区域,存放对象相关信息,分为了新生代和老年代,内存比例一般为1:2,新生代的Eden区域内存不够的时候发生Minor GC,老年代内存不够的时候发生Full GC
  • 方法区:存放有关类的信息。存放类信息、静态变量、常量、运行时常量池等信息。JDK1.8之前用永久代实现,JDK1.8之后采用元空间实现,元空间使用的是本地内存,而非存放在JVM结构当中

什么时候会内存溢出

堆内存溢出:

  1. 对象一直创建而不被回收的时候
  2. 加载的类越来越多的时候
  3. 虚拟机栈的线程越来越多的时候(如果应用程序创建了过多的线程,并且每个线程都创建了大量的对象,堆内存的使用量就会增加。)

栈溢出:

  1. 方法调用次数太多,一般为递归调用不当造成

JVM有哪些垃圾回收算法

标记清除算法:标记不需要回收的对象(首先会进行标记阶段。从根对象(如全局变量、栈中的引用等)开始,通过可达性分析或其他方式,遍历对象图谱,将所有与根对象可达的对象标记为存活对象),然后清除没有标记的对象,这种方式会造成许多内存碎片。

复制算法:将内存将内存分为两块,只使用一块,进行垃圾回收的时候,先将存活的对象复杂到另一块区域,然后在清空之前的区域。(新生代中的from区和to区用的就是类似这种算法)

标记整理算法:与标记清除算法类似,但是在标记之后,将存活的对象向一方移动,然后清除边界外的垃圾对象。应用于老年代的垃圾回收

GC如何判断对象可以被回收

引用计数法:为每个对象添加引用计数器,当引用个数为0的时候判定为可以被回收,但存在有两个对象相互引用导致无法回收的问题

可达性分析算法:从GCRoots开始向下搜索,搜索过的路径称为引用链,对于GCRoots没有任何引用的对象,则判定可以被回收

什么是GCRoots:

在Java中,以下几种情况可以被定义为GCRoots:

  1. 栈中的引用:包括局部变量、方法参数和操作数栈中的引用。
  2. 静态变量:属于类的静态字段,因为它们始终存在于内存中。
  3. JNI(Java Native Interface)引用:JNI是Java与本地代码交互的机制,JNI引用指向在本地代码中创建的Java对象。
  4. 虚拟机内部的引用:包括虚拟机常量引用和系统类加载器等特殊类的引用。
  5. 线程相关引用:例如当前活动线程的引用或线程的任务队列中的引用。

典型的垃圾回收器

CMS:

以最小的停顿时间为目标,只运行在老年代的垃圾回收器,使用标记清除算法,可以并发收集(标记和清除阶段)

CMS回收器采用了一种并发标记清除算法,具有以下几个主要特点:

  1. 并发:CMS回收器的标记和清除阶段是与应用程序线程并发执行的。它尽量减少垃圾收集期间的停顿时间,以提供更好的响应性能。在标记阶段,由于与应用程序线程同时运行,可以减少暂停时间。
  2. 低停顿:CMS回收器的主要目标是减少应用程序的停顿时间。通过在标记和清除阶段的并发执行,可以避免全局停顿。但为了达到低停顿的效果,CMS回收器会牺牲一部分吞吐量。
  3. 分代收集:CMS回收器主要关注老年代的回收,因为老年代通常包含更多的存活对象。对于新生代,CMS回收器通常与其他回收器(如Serial或ParNew)结合使用。
  4. 标记-清除算法:CMS回收器采用标记-清除算法,首先进行并发标记,然后进行并发清除。标记过程中使用“标记”位来标记存活对象,而清除阶段会清除所有未被标记的对象,释放内存空间。
  5. 空间碎片:CMS回收器在并发清除阶段不会移动对象,这可能导致内存碎片的产生。为了解决内存碎片问题,CMS回收器提供了“空闲列表”来尽量利用连续的内存空间。

        需要注意的是,CMS回收器适用于具有大内存、长时间运行的应用程序,并且强调减少停顿时间。但由于并发执行和空间碎片的特点,它可能会导致一些额外的CPU开销,并且在极端情况下可能会触发Full GC。

G1:

JDK1.9之后的默认的垃圾回收器,注重响应速度,支持并发,采用标记整理+复制算法回收内存,使用可达性分析判断对象是否应该被回收。

G1回收器具有以下几个主要特点:

  1. 区域化的堆布局:与传统的分代堆模型不同,G1将堆划分为多个大小相等的区域。每个区域可以是Eden、Survivor、Old或Huge Region之一。这种区域化的布局有助于对垃圾回收的控制和优化。
  2. 并发标记:G1回收器使用并发标记算法来标记存活对象。在标记阶段,应用程序线程与垃圾收集线程并发执行,从而减少了停顿时间。
  3. 多线程并行处理:G1回收器在标记和清除阶段使用多个线程来并行处理垃圾回收任务,以提高回收效率。
  4. 基于回收价值的优先级:G1回收器根据每个区域内的回收价值来选择优先回收的区域,这样可以优先回收那些包含大量垃圾的区域,从而提高回收效率。
  5. 整理空闲:G1回收器在执行垃圾回收时会进行部分或完全的内存整理,以减少内存碎片,提高内存使用效率。
  6. 可预测的停顿时间:G1回收器通过将回收任务划分为多个短暂的回收周期来控制停顿时间。用户可以通过配置参数来指定期望的最大停顿时间,G1回收器会尽量在这个时间范围内完成垃圾回收。

        G1回收器适用于具有大内存、需要低延迟和可预测停顿时间的应用程序。相对于CMS回收器,G1回收器提供了更好的吞吐量和停顿时间控制。但与此同时,它也引入了一些额外的开销,如内存开销、CPU开销和GC负载。

类加载器和双亲委派机制:

类加载器

        类加载器负责从文件系统、网络或其他来源加载类的字节码,并将其转换为JVM可以理解的格式。JVM支持多个类加载器,每个加载器都负责加载特定类型的类。

从父加载器到子类加载器分别为:

BootStrapClassLoader(启动类加载器)         加载路径——JAVA_HOME/jre/lib

ExtensionClassLoader(扩展类加载器)         加载路径——JAVA_HOME/jre/lib/ext

ApplicationClassLoader (应用程序类加载器)       加载路径——classPath

双亲委派机制

        双亲委派机制是类加载器的一种工作方式,它通过层级关系进行加载类的过程。当一个类加载器需要加载一个类时,它首先将这个任务委派给它的父类加载器,父类加载器再将任务委派给它的父类加载器,直至最终委派给顶层的启动类加载器。只有当父类加载器无法加载这个类时,子加载器才会尝试自己加载。

优势

  1. 安全性: 假设有一个恶意代码想要替换Java核心API类中的某个类,比如java.lang.String。由于双亲委派机制的存在,该加载请求会首先被委派给启动类加载器进行处理。启动类加载器负责加载核心Java API,并将其保护起来,以防止被篡改或替换。因此,即使存在恶意代码尝试加载java.lang.String类,由于该类已由启动类加载器加载,恶意代码的加载请求将被拒绝。

  2. 避免重复加载: 假设我们有两个不同的类加载器,分别是ClassloaderAClassloaderB,它们都可以加载同一个类com.example.MyClass。如果没有双亲委派机制,当需要加载com.example.MyClass时,ClassloaderAClassloaderB可能会分别加载自己的版本,导致在JVM中存在多个com.example.MyClass类的副本,可能会引发类冲突和不一致的问题。而通过双亲委派机制,当ClassloaderAClassloaderB都遵循委派机制,它们都会将加载请求委派给父类加载器,最终由启动类加载器加载该类。这样,只有一个版本的com.example.MyClass类会被加载,避免了重复加载和冲突。

  3. 存在性检查: 当一个类加载器需要加载某个类时,它会先询问父类加载器是否已经加载过该类。如果父类加载器已经加载了该类,那么子类加载器就无需再次加载,直接使用父类加载器加载的类。这样做可以提高加载效率,避免不必要的重复加载操作。例如,当一个应用程序使用Class.forName("com.example.MyClass")动态加载某个类时,首先会询问应用程序类加载器(Application Class Loader)是否已经加载了该类。如果已经加载,则可以直接使用,而不需要再次加载。

JVM中有哪些引用

        在JVM(Java虚拟机)中,引用是指对对象的间接访问。引用允许我们操作和处理对象,而无需直接访问对象本身。引用是一种对内存中对象的标识,通过引用可以定位和操作存储在堆中的对象。

        引用在Java中有不同的类型,包括强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)和虚引用(Phantom Reference)。它们的主要区别在于对垃圾回收的影响和生命周期的长短。

  1. 强引用:new的对象。哪怕内存溢出也不会回收
  2. 软引用:只有内存不足时才会回收
  3. 弱引用:每次垃圾回收都会回收
  4. 虚引用:必须配合引用队列使用,一般用于追踪垃圾回收动作、

虚引用

当一个对象只有虚引用指向它时,无论何时垃圾回收器决定回收该对象,它都可以立即进行回收。在回收对象之前,垃圾回收器会将这个对象放入一个特殊的引用队列中。

使用虚引用的好处是,我们可以通过检查引用队列来确定哪些对象已经被回收。这样,我们可以在对象被回收时采取一些额外的操作或记录。例如,我们可以在对象被回收时进行资源清理或日志记录。

要注意的是,虚引用本身并不能保持对象的存活,也不能通过虚引用来访问对象。它仅仅是在对象被回收前提供了一个通知的机制,以便我们可以观察和处理对象的回收过程。

所以,虚引用的主要作用是帮助开发者了解对象的回收情况,并在需要时执行一些附加的操作。

 

类加载的过程

(1)加载:将字节码通过二进制的形式转化到方法区中的运行数据区当中。

(2)连接:

  • 验证:验证字节码文件的正确性
  • 准备:正式为类变量在方法区中分配内存,并设置默认的初始值,final类型的变量是在编译时就赋值
  • 解析:将常量池中的符号引用(如类的全限定名)解析为直接引用(类再实际内存中的地址)

(3)初始化:执行类构造器(不是常规的那种类的构造方法),为静态变量赋初值并初始化静态代码块。

JVM类初始化的顺序

父类静态代码块和静态成员变量-》

子类静态代码块和静态成员变量-》

父类代码块和普通成员变量-》

子类代码块和普通成员变量-》

子类构造方法

对象的创建过程

(1)检查类是否被加载,如果没加载就先加载类

(2)为对象在堆中分配内存,使用CAS方式分配,防止在为A进行内存分配的时候,执行当前地址的指针还没有来得及修改,对象B就拿来分配内存(让A分配完了再让B分配)

(3)初始化,将对象中的属性都分配为0值或者为null

(4)设置对象头

(5)为属性赋值和执行构造方法

对象头中有哪些信息

1.Markword

  • 锁信息
  • hashcode
  • GC标记

2.类指针KlassPointer

JVM的内存参数

-Xmx[]:堆空间最大内存

-Xms[]:堆空间最小内存,一般设置成跟堆空间最大内存一样的

-Xmn[]:新生代的最大内存

-xx:[survivorRatio=3]:Eden区与from+to区的比例为3:1,默认为4:1

-xx[use 垃圾回收器名称]:指定垃圾回收器

-xss:设置单个线程栈大小

一般设堆空间为最大可用物理地址的百分之80
 

GC的回收机制与原理

        GC的目的实现内存的自动释放,使用可达性分析算法判断对象是否可被回收,采用了分代回收的思想,将堆分为了新生代、老年代;新生代中采取了复制算法,老年代中采用了标记整理算法,当新生代内存不够的时候发生Minor GC,老年代内存不够的时候发生Full GC

相关文章:

JVM加强

目录 JVM运行时的数据区(内存结构): 线程独享: 线程共享: 什么时候会内存溢出 JVM有哪些垃圾回收算法 GC如何判断对象可以被回收 典型的垃圾回收器 CMS: G1: 类加载器和双亲委派机制&a…...

解决Oracle中XML插入数据时的空格问题

🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…...

微服务中间件--分布式事务

分布式事务 a.理论基础1) CAP定理2) BASE理论 b.Seata1) XA模式1.a) 实现XA模式 2) AT模式3) TCC模式3.a) 代码实现 4) Saga模式5) 四种模式对比6) TC的异地多机房容灾架构 a.理论基础 1) CAP定理 分布式系统有三个指标: Consistency(一致性&#xff…...

计算机网络(9) --- 数据链路层与MAC帧

计算机网络(8) --- IP与IP协议_哈里沃克的博客-CSDN博客IP与IP协议https://blog.csdn.net/m0_63488627/article/details/132155460?spm1001.2014.3001.5502 目录 1.MAC帧 1.MAC地址 2.MAC帧报头 3.资源碰撞 4.MTU 1.对IP协议的影响 2.对UDP协议…...

【学会动态规划】环绕字符串中唯一的子字符串(25)

目录 动态规划怎么学? 1. 题目解析 2. 算法原理 1. 状态表示 2. 状态转移方程 3. 初始化 4. 填表顺序 5. 返回值 3. 代码编写 写在最后: 动态规划怎么学? 学习一个算法没有捷径,更何况是学习动态规划, 跟我…...

CNN卷积详解(三)

一、卷积层的计算 4 ∗ * ∗ 4的输入矩阵 I I I 和 3 ∗ * ∗ 3 的卷积核 K K K: 在步长(stride)为 1 时,输出的大小为 ( 4 − 3 1 ) ( 4 − 3 1) 计算公式: ● 输入图片矩阵 I I I 大小: w w w w ww ●…...

使用 Amazon Redshift Serverless 和 Toucan 构建数据故事应用程序

这是由 Toucan 的解决方案工程师 Django Bouchez与亚马逊云科技共同撰写的特约文章。 带有控制面板、报告和分析的商业智能(BI,Business Intelligence)仍是最受欢迎的数据和分析使用场景之一。它为业务分析师和经理提供企业的过去状态和当前状…...

CentOS 上快速安装包管理工具Conda

要在 CentOS 上安装 Conda,您可以按照以下步骤进行操作: 1. 下载 Miniconda 或 Anaconda 安装脚本: Miniconda:适用于轻量级安装的 Miniconda 版本。 wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.…...

opencv-手势识别

# HandTrackingModule.py import cv2 import mediapipe as mpclass HandDetector:"""使用mediapipe库查找手。导出地标像素格式。添加了额外的功能。如查找方式,许多手指向上或两个手指之间的距离。而且提供找到的手的边界框信息。"""…...

【SA8295P 源码分析】10 - HQX Display(OpenWFD)qcdisplaycfg_ADP_STAR_LA.xml 配置文件解析

【SA8295P 源码分析】10 - HQX Display(OpenWFD)qcdisplaycfg_ADP_STAR_LA.xml 配置文件解析 一、HQX Display 介绍1.1 OpenWF Display Driver二、HQX Display 配置文件参数解析2.1 qcdisplaycfg.xml 配置文件2.1 配置两个 DPUs in QNX2.1.1 配置 graphics_ADP_STAR.conf : …...

达梦数据库权限和预定角色介绍

概述 本文对达梦数据库数据库和对象权限及DM预定义角色及角色创建进行介绍。 1.权限管理 用户权限有两类:数据库权限和对象权限。 数据库权限主要是指针对数据库对象的创建、删除、修改的权限,对数据库备份等权限。 数据库权限一般由 SYSDBA、SYSAU…...

Python编程从入门到实践_8-8 用户的专辑_答案

Python编程从入门到实践_8-8 用户的专辑_答案 我也看了一些其他人的答案,很多的答案存在问题,每次调用函数 make_album() 后生成一个专辑字典会覆盖上次调用函数 make_album() 生成的字典,不符合题意。 我采取的解决方案是添加一个空列表 …...

HummingBird 基于 Go 开源超轻量级 IoT 物联网平台

蜂鸟(HummingBird) 是 Go 语言实现的超轻量级物联网开发平台,包含设备接入、产品管理、物模型、告警中心、规则引擎等丰富功能模块。系统采用GoLang编写,占用内存极低, 单物理机可实现百设备的连接。 在数据存储上&…...

10.小程序样式

样式 css部分样式不支持,并且添加了rpx属性,小程序开发的时候应该使用rpx,而不是px,因为rpx是将移动端的屏幕大小分为750份,会自动按设备的大小去适配;我们在开发时应该以iphone6为基准的设备进行开发&…...

Flink 流式读写文件、文件夹

文章目录 一、flink 流式读取文件夹、文件二、flink 写入文件系统——StreamFileSink三、查看完整代码 一、flink 流式读取文件夹、文件 Apache Flink针对文件系统实现了一个可重置的source连接器,将文件看作流来读取数据。如下面的例子所示: StreamExe…...

【SA8295P 源码分析】64 - QNX 与 Android GVM 显示 Dump 图片方法汇总

【SA8295P 源码分析】64 - QNX 与 Android GVM 显示 Dump 图片方法汇总 一、QNX侧1.1 surfacedump 功能1.2 screenshot 功能二、Android GVM 侧2.1 screencap -p 导出 PNG 图片2.2 screencap 不加 -p 参数,导出 RGB32 图片2.3 dumpsys SurfaceFlinger --display-id 方法系列文…...

字符串旋转(1)

目录 ​编辑 题目要求😍: 题目内容❤: 题目分析📚: 主函数部分📕:​编辑 方法一🐒: 方法二🐒🐒: 方法三🐒&#x1f…...

【SA8295P 源码分析】13 - Android GVM 虚拟机 QUPv3 UART / SPI / I2C功能配置及透传配置

【SA8295P 源码分析】13 - Android GVM 虚拟机 QUPv3 UART / SPI / I2C功能配置及透传配置 一、QUP v3 介绍二、QUP v3 UART 功能配置2.1 TrustZone 域 Uart 资源权限配置:以 QUPV3_0_SE2 为例2.2 QNX Host 域关闭 Uart 资源:以 QUPV3_0_SE2 为例2.3 Android Kernel 域使能 U…...

STM32 F103C8T6学习笔记10:OLED显示屏GIF动图取模—简易时钟—动图手表的制作~

今日尝试做一款有动图的OLED实时时钟,本文需要现学一个OLED的GIF动图取模 其余需要的知识点有不会的可以去我 STM32 F103C8T6学习笔记 系列专栏自己查阅把,闲话不多,直接开肝~~~ 文章提供源码,测试工程下载,测试效…...

大数据课程K3——Spark的常用案例

文章作者邮箱:yugongshiye@sina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 掌握Spark的常用案例——WordCount; ⚪ 掌握Spark的常用案例——求平均值; ⚪ 掌握Spark的常用案例——求最大值和最小值; ⚪ 掌握Spark的常用案例——TopK; ⚪ 掌握Spark的常用案例…...

造相-Z-Image本地AI工作流整合:Z-Image+ComfyUI节点化扩展可能性探讨

造相-Z-Image本地AI工作流整合:Z-ImageComfyUI节点化扩展可能性探讨 1. 项目概述与核心价值 造相-Z-Image是一款基于通义千问官方Z-Image模型的本地化文生图解决方案,专为RTX 4090显卡用户深度优化。这个项目最大的特点是将强大的AI图像生成能力完整地…...

手把手教你用LVGL+FreeRTOS在STM32上实现多页面切换(附完整源码)

手把手教你用LVGLFreeRTOS在STM32上实现多页面切换(附完整源码) 在嵌入式GUI开发中,页面管理机制的设计直接影响用户体验和代码可维护性。本文将深入探讨如何基于LVGL和FreeRTOS构建一个高效的多页面切换框架,从数据结构设计到实…...

单片机核心功能解析与实战技巧

1. 单片机学习的核心功能解析作为一名在嵌入式领域摸爬滚打多年的工程师,我深知单片机学习的关键不在于死记硬背,而在于掌握几个核心功能的底层逻辑和应用场景。很多初学者容易陷入"学了很多却不会用"的困境,根本原因就是没有抓住这…...

【安全心法】别用定时器喂狗!撕碎看门狗的伪安全面具,直面“僵尸系统”的物理绞肉机

摘要:在硬实时控制系统中,硬件看门狗被奉为防止系统死机的终极神明。但无数软硬件工程师出于偷懒或对底层架构的无知,将“喂狗”动作外包给了高频的定时器中断或最高优先级的独立任务。本文将彻底摒弃代码,纯粹从系统架构的安全哲…...

On the Spectral Geometry of Cognitive Manifolds and the Emergence of Physical Laws

On the Spectral Geometry of Cognitive Manifolds and the Emergence of Physical Laws (A Noncommutative Framework for Free Will, Physical Constants, and Arithmetical Obstructions)作者:方见华 单位:世毫九实验室摘要&am…...

ai辅助开发:让快马智能生成win11安装openclaw的交互式诊断助手

最近在折腾Win11系统上安装OpenClaw这个工具时,发现手动安装过程特别容易踩坑。从依赖版本冲突到权限问题,稍不注意就会卡住。后来尝试用InsCode(快马)平台的AI辅助功能,意外发现它能生成一个智能安装助手,把整个流程变得特别顺畅…...

嵌入式C轻量序列化库:结构体打包与位操作零依赖实现

1. 项目概述dot_util是一个轻量级、零依赖的嵌入式 C 语言工具库,专为资源受限的 MCU(如 Cortex-M0/M3/M4、RISC-V 32 位内核)设计。其核心定位并非通用算法库或 HAL 封装,而是聚焦于底层数据序列化与结构体操作的工程痛点&#x…...

Vue 3 到底好在哪里?一文看懂 Composition API 的三大核心优势

Vue 3 到底好在哪里?一文看懂 Composition API 的三大核心优势 在前端框架的演进历程中,Vue 3 的发布堪称里程碑事件。其核心亮点之一——Composition API,彻底重构了组件逻辑的组织方式,解决了传统 Options API 在大型项目中的痛…...

Claude Code 最佳实践:构建可验证、可治理、可扩展的生产级分布式系统

Claude Code 最佳实践:构建可验证、可治理、可扩展的生产级分布式系统 在很多团队的第一印象里,Claude Code 只是“更强一点的命令行编码助手”。但一旦进入中大型研发场景,你很快会发现,真正决定它价值上限的,不是单次补全能力,而是它是否能够被纳入一套可验证、可治理…...

Tsuru平台安全加固终极指南:10个关键步骤保护你的PaaS环境

Tsuru平台安全加固终极指南:10个关键步骤保护你的PaaS环境 【免费下载链接】tsuru Open source and extensible Platform as a Service (PaaS). 项目地址: https://gitcode.com/gh_mirrors/ts/tsuru Tsuru是一款开源且可扩展的平台即服务(PaaS)解决方案&…...