JVM 重要知识梳理

news2024/10/6 1:34:35

一、java内存区域

  • 程序计数器:线程私有,唯一一个不会出现outOfMemoryError的内存区域
  • 虚拟机栈:线程私有,栈由一个个栈帧组成,而每个栈帧中都拥有:局部变量表、操作数栈、动态链接、方法返回地址。
  • 本地方法栈:线程私有,为虚拟机栈使用到的Native方法服务
  • 堆:线程共享,内存最大的一块,唯一目的就是存放对象实例,几乎所有的对象实例以及数组都在这里分配内存
  • 方法区(1.8之后叫元空间):线程共享,逻辑区域,存储已被虚拟机加载的:类信息、字段信息、方法信息、常量、静态变量、即时编译期编译后的代码缓存等数据
  • 直接内存:线程共享,特殊的内存缓冲区,是通过JNI的方式在本地内存上分配的 。

【重】为什么将永久代替换为元空间?

1.整个永久代有一个JVM本身设置的固定大小上限,无法进行调整,而元空间使用的是本地内存,受本机可用内存限制,溢出几率比原来更小。

2.元空间里面存放的是类的元数据,这样加载多少类的元数据不由MaxPermSize控制了,而由系统的实际可用空间来控制,这样能加载更多的类。

3.在jdk8中,合并HotPot和JRockit的代码时,JRockit从来没有一个叫永久代的东西,因此合并后无序再增加。

【重】jdk1.7为什么将字符串常量池移动到堆中?

因为永久代(方法区的实现)的GC回收率太低了,只有在整堆收集(Full GC)的时候才会被执行GC。java程序中通常会有大量的被创建的字符串等待回收,将字符串常量池放到堆中,能够高效及时地回收字符串内存。

二、垃圾收集算法

  • 标记-清除(Mark-and-Sweep)首先标记出所有不需要回收的对象,在标记完成后统一回收掉所有没有被标记的对象。【效率低,且会产生大量不连续的内存碎片】

  • 复制算法:它可以将内存分为大小相同的两块,每次使用其中的一块。当这一块的内存使用完后,就将还存活的对象复制到另一块去,然后再把使用的空间一次清理掉。这样就使每次的内存回收都是对内存区间的一半进行回收。【可用内存变小、不适合老年代】

  • 标记-整理(Mark-and-Compact)算法是根据老年代的特点提出的一种标记算法,标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象回收,而是让所有存活的对象向一端移动,然后直接清理掉端边界以外的内存。【效率不高,适合老年代】

  • 分代收集算法:当前虚拟机的垃圾收集都采用分代收集算法,这种算法没有什么新的思想,只是根据对象存活周期的不同将内存分为几块。一般将 Java 堆分为新生代和老年代,这样我们就可以根据各个年代的特点选择合适的垃圾收集算法【新生代采用标记-复制算法,老年代采用标记-整理算法

三、垃圾收集器

  1. Serial(串行)收集器是最基本、历史最悠久的垃圾收集器了。它的 “单线程” 的意义不仅仅意味着它只会使用一条垃圾收集线程去完成垃圾收集工作,更重要的是它在进行垃圾收集工作的时候必须暂停其他所有的工作线程( "Stop The World" ),直到它收集结束。【效率高、体验感不好】

  2. ParNew 收集器其实就是 Serial 收集器的多线程版本,除了使用多线程进行垃圾收集外,其余行为(控制参数、收集算法、回收策略等等)和 Serial 收集器完全一样。

  3. Parallel Scavenge 收集器也是使用标记-复制算法的多线程收集器,它看上去几乎和 ParNew 都一样。关注点是吞吐量(高效率的利用 CPU)

  4. Serial Old收集器:Serial 收集器的老年代版本,它同样是一个单线程收集器。它主要有两大用途:一种用途是在 JDK1.5 以及以前的版本中与 Parallel Scavenge 收集器搭配使用,另一种用途是作为 CMS 收集器的后备方案。

  5. Parallel Old收集器:Parallel Scavenge 收集器的老年代版本。使用多线程和“标记-整理”算法。在注重吞吐量以及 CPU 资源的场合,都可以优先考虑 Parallel Scavenge 收集器和 Parallel Old 收集器。

  6. CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。它非常符合在注重用户体验的应用上使用。CMS(Concurrent Mark Sweep)收集器是 HotSpot 虚拟机第一款真正意义上的并发收集器,它第一次实现了让垃圾收集线程与用户线程(基本上)同时工作。【对CPU资源敏感、无法处理浮动垃圾、会产生大量空间碎片】

  7. G1 收集器在后台维护了一个优先列表,每次根据允许的收集时间,优先选择回收价值最大的 Region(这也就是它的名字 Garbage-First 的由来) 。这种使用 Region 划分内存空间以及有优先级的区域回收方式,保证了 G1 收集器在有限时间内可以尽可能高的收集效率(把内存化整为零)。从 JDK9 开始,G1 垃圾收集器成为了默认的垃圾收集器。运作过程:初始标记、并发标记、最终标记、筛选回收。

【重】虚引用与软引用和弱引用的一个区别在于: 虚引用必须和引用队列(ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。程序如果发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。

软引用可以加速 JVM 对垃圾内存的回收速度,可以维护系统的运行安全,防止内存溢出(OutOfMemory)等问题的产生

【重】对象可以被回收,就代表一定会被回收吗?

即使在可达性分析法中不可达的对象,也并非是“非死不可”的,这时候它们暂时处于“缓刑阶段”,要真正宣告一个对象死亡,至少要经历两次标记过程;可达性分析法中不可达的对象被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行 finalize 方法。当对象没有覆盖 finalize 方法,或 finalize 方法已经被虚拟机调用过时,虚拟机将这两种情况视为没有必要执行。

被判定为需要执行的对象将会被放在一个队列中进行第二次标记,除非这个对象与引用链上的任何一个对象建立关联,否则就会被真的回收

四、内存分配策略

部分收集 (Partial GC):

  • 新生代收集(Minor GC / Young GC):只对新生代进行垃圾收集;

  • 老年代收集(Major GC / Old GC):只对老年代进行垃圾收集。需要注意的是 Major GC 在有的语境中也用于指代整堆收集;

  • 混合收集(Mixed GC):对整个新生代和部分老年代进行垃圾收集。

整堆收集 (Full GC):收集整个 Java 堆和方法区

五、类加载的过程

它的整个生命周期可以简单概括为 7 个阶段::加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)。

六、类加载器

  • 类加载器是一个负责加载类的对象,用于实现类加载过程中的加载这一步。

  • 每个 Java 类都有一个引用指向加载它的 ClassLoader

  • 数组类不是通过 ClassLoader 创建的(数组类没有对应的二进制字节流),是由 JVM 直接生成的。

类加载器的主要作用就是加载 Java 类的字节码( .class 文件)到 JVM 中(在内存中生成一个代表该类的 Class 对象)

.双亲委派【重】
  • ClassLoader 类使用委托模型来搜索类和资源。

  • 双亲委派模型要求除了顶层的启动类加载器外,其余的类加载器都应有自己的父类加载器。

  • ClassLoader 实例会在试图亲自查找类或资源之前,将搜索类或资源的任务委托给其父类加载器。

简单总结一下双亲委派模型的执行流程:

  • 在类加载的时候,系统会首先判断当前类是否被加载过。已经被加载的类会直接返回,否则才会尝试加载(每个父类加载器都会走一遍这个流程)。

  • 类加载器在进行类加载的时候,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成(调用父加载器 loadClass()方法来加载类)。这样的话,所有的请求最终都会传送到顶层的启动类加载器 BootstrapClassLoader 中。

  • 只有当父加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载(调用自己的 findClass() 方法来加载类)。

  • 如果子类加载器也无法加载这个类,那么它会抛出一个 ClassNotFoundException 异常。

七、虚拟机性能监控

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

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

相关文章

Prompt Learning:人工智能的新篇章

开篇:AI的进化之旅 想象一下,你正在和一位智能助手对话,它不仅理解你的问题,还能提出引导性的问题帮助你更深入地思考。这正是prompt learning的魔力所在——它让机器学习模型变得更加智能和互动。在这篇博客中,我们将…

【JavaScript】面试手撕柯里化函数

🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 ​💫个人格言: "如无必要,勿增实体" 文章目录 引入柯里化定义实现快速使用柯里化的作用提高自由度bind函数 参考资料 引入 上周…

git区域与对象

大纲 工作区(workspace directory):本机的代码项目,是一种沙箱环境 暂存区(stage index):工作区在程序员写程序的过程中会发生无数次改动,git不可能记录每一次的改动,这些改动的过程在暂存区负责记录,暂存区会将最终的状态随着程序员的提交…

springboot与elasticsearch-7.16.2的基础CRUD使用——入门向

highlight: an-old-hope 基于elasticsearch-7.16.2 ,使用的是旧版的高级客户端 restHighLevelClient springboot版本2.6.13 项目原代码地址 https://gitee.com/kenwm/es7demo.git 参考博客 1、SpringBoot集成ElasticSearch,实现模糊查询,批…

学python新手如何安装pycharm;python小白如何安装pycharm

首先找到官网: Download PyCharm: The Python IDE for data science and web development by JetBrains 打开后选择下载,下图标红部分 点击exe程序,点击下一步! 选择安装路径,下一步 弹出界面全选 选择默认 然后直接…

Spring核心接口:BeanFactory接口

一图胜千言 BeanFactory 属性&方法解析 点击展开注意:以上代码仅供参考,可能存在不完整或不准确的情况。 public interface BeanFactory {// 根据Bean名称返回Bean实例。// 如果Bean不存在,则抛出NoSuchBeanDefinitionException异常。Obj…

华为机考:HJ43 迷宫问题

华为机考:HJ43 迷宫问题 描述 DFS 从迷宫入口开始进行dfs搜索,每次进入一个点,将其加入临时路径数组中,把该位改成0表示不能进入,然后依次搜索该位下、右、上、左四个方向的点,如果搜索的这个点可以进入则…

【机器学习智能硬件开发全解】(二)—— 政安晨:嵌入式系统基本素养【处理器原理】

嵌入式系统的基本素养包括以下几个方面: 硬件知识:嵌入式系统通常由硬件和软件组成,了解和熟悉硬件的基本知识,包括微处理器、存储器、外设等,并了解它们的工作原理和特性。 软件编程:熟悉至少一种编程语言…

STM32模拟I2C控制TM1650数码管显示电压电流

模拟I2C控制TM1650数码管显示电压电流 数码管的逻辑TM1650 原理模拟I2C的实现TM1650驱动电压电流显示 数码管的逻辑 通过数码管来表示字符。 数码管的abcdefg和dp分别对应这发送过去的8位数据位比如0x3F -> 0011 1111 表示0字符。 如果要加上小数点则在最高位加一&#xf…

同步整流芯片 支持12V降5V 24V降5V 24V降12V 降压芯片 H4122

惠海H4122降压恒压芯片的工作原理: 主要是通过内部电路和算法来控制和调节输出电压,使其保持恒定。 输入电压:芯片接收一个较高的输入电压,如12V、24V或36V。 开关电源转换器:芯片内部通常包含一个或多个开关电源转…

【python pyinstaller库】pyinstaller介绍、安装、以及相关重点知识

PyInstaller是一个在Windows、GNU/Linux、macOS等平台下将Python程序冻结(打包)为独立可执行文件的工具, 用于在未安装Python的平台上执行Python编写的应用程序。 相比类似工具,它的主要优点是 PyInstaller 与 Python 3.7-3.10 一起工作&…

StarRocks实战——云览科技存算分离实践

目录 背景 一、平台现状&痛点 1.1 使用组件多,维护成本高 1.2 链路冗长,数据时效性难以保证 1.3 服务稳定性不足 二、StarRocks 存算分离调研 2.1 性能对比 2.2 易用性 2.3 存储成本 三、StarRocks 存算分离实践 3.1 查询优化 3.1.1 物化…

SyntaxError: Unexpected end of JsON input J50N.parse....报错

const userInfoJSON.parse(uni.getStorageSync(userInfo))改成 const userInfouni.getStorageSync(userInfo)&& JSON.parse(uni.getStorageSync(userInfo)) //不报错

ChatGPT国内能用吗?中国用户怎么才能使用ChatGPT?

与ChatGPT类似的国内网站,他们都能提供和ChatGPT相似的能力,而且可以在国内直接使用。 点击直达方式 百科GPT官网:baikegpt.cn ChatGPT是基于GPT-3.5架构的语言模型的一个实例,由OpenAI开发。以下是ChatGPT的发展历史&#xff1…

深入理解Python中的面向对象编程(OOP)【第129篇—Scikit-learn的入门】

深入理解Python中的面向对象编程(OOP) 在Python编程领域中,面向对象编程(Object-Oriented Programming,简称OOP)是一种强大而灵活的编程范式,它允许开发者以对象为中心组织代码,使得…

Redis7.2.4分片集群搭建

Redis分片集群搭建 1.集群结构 分片集群需要的节点数量较多,这里我们搭建一个最小的分片集群,包含3个master节点,每个master包含一个slave节点,结构如下: 信息如下: IPPORT角色glnode036379slaveglnode0…

JavaEE:文件IO

硬盘 文件指的是硬盘/磁盘上的文件 ⚠硬盘 ≠ 磁盘 磁盘属于外存的一种;而软盘,硬盘(机械硬盘)这种属于用磁性介质来存储二进制数据 ssd硬盘(固态硬盘),内部完全是集成电路,和磁…

手写简易操作系统(七)--加载操作系统内核

前情提要 上一节中,我们开启了内存分页,这一节中,我们将加载内核,内核是用C语言写的,C语言编译完了是一段ELF可加载程序,所以我们需要学会解析ELF格式文件,并将内核加载到内存 一、ELF格式 程…

(黑马出品_高级篇_04)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式

(黑马出品_高级篇_04)SpringCloudRabbitMQDockerRedis搜索分布式 微服务技术——可靠性消息服务 今日目标服务异步通信-高级篇1.消息可靠性1.1.生产者消息确认1.1.1.修改配置1.1.2.定义Return回调1.1.3.定义ConfirmCallbac…

【LeetCode热题100】2. 两数相加(链表)

一.题目要求 给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。 请你将两个数相加,并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外,这两个数…