Java [ 进阶 ] 深入理解 JVM

✨探索Java基础   深入理解 JVM✨

深入理解 JVM:结构与垃圾回收机制

Java 虚拟机(JVM)是 Java 程序运行的核心,了解 JVM 的内部结构和垃圾回收机制对优化 Java 应用性能至关重要。本文将深入探讨 JVM 的结构和垃圾回收机制,并附上一些代码示例以帮助理解。

JVM 结构

JVM 是一种抽象的计算机,负责执行 Java 字节码程序。JVM 的内部结构包括以下几个关键组件:

  1. 类加载器子系统(Class Loader Subsystem)

    • 启动类加载器(Bootstrap ClassLoader):加载核心类库,如 rt.jar
    • 扩展类加载器(Extension ClassLoader):加载扩展库,如 ext 目录下的类。
    • 应用类加载器(Application ClassLoader):加载用户类路径(classpath)下的类。
    public class ClassLoaderExample {
        public static void main(String[] args) {
            // 获取系统类加载器
            ClassLoader classLoader = ClassLoader.getSystemClassLoader();
    
            // 打印类加载器的名称
            System.out.println("System ClassLoader: " + classLoader);
    
            // 获取扩展类加载器
            ClassLoader extClassLoader = classLoader.getParent();
            System.out.println("Extension ClassLoader: " + extClassLoader);
    
            // 获取启动类加载器(通常返回 null,因为它是用本地代码实现的)
            ClassLoader bootstrapClassLoader = extClassLoader.getParent();
            System.out.println("Bootstrap ClassLoader: " + bootstrapClassLoader);
        }
    }
    

  2. 运行时数据区(Runtime Data Areas)

    • 方法区(Method Area):存储类信息、常量、静态变量、即时编译器编译后的代码。方法区是线程共享的。
    • 堆(Heap):存储所有对象实例和数组,堆是线程共享的,是垃圾回收的主要区域。
    • 栈(Stack):每个线程都有自己的栈,存储方法调用信息(栈帧),包括局部变量、操作数栈、方法返回地址等。
    • 程序计数器(Program Counter Register):每个线程都有自己的程序计数器,存储当前线程执行的字节码指令地址。
    • 本地方法栈(Native Method Stack):为 JVM 执行本地方法(Native Methods)提供栈空间。
  3. 执行引擎(Execution Engine)

    • 解释器(Interpreter):逐行解释字节码,并将其转换为机器码执行。
    • 即时编译器(JIT Compiler):将热点代码编译成机器码,以提高执行效率。
    • 垃圾回收器(Garbage Collector):负责自动回收不再使用的对象所占用的内存。
    public class ExecutionEngineExample {
        public static void main(String[] args) {
            // 使用 JIT 编译器
            long startTime = System.nanoTime();
            for (int i = 0; i < 1_000_000; i++) {
                double value = Math.sqrt(i); // 假设这是热点代码
            }
            long endTime = System.nanoTime();
            System.out.println("Execution time with JIT: " + (endTime - startTime) + " ns");
        }
    }
    

  4. 本地方法接口(Native Method Interface, JNI)

    • 提供与本地代码(如 C、C++)交互的接口,使得 Java 可以调用操作系统的本地方法。
    public class NativeMethodExample {
        static {
            System.loadLibrary("nativeLib"); // 加载本地库
        }
    
        // 声明本地方法
        public native void nativeMethod();
    
        public static void main(String[] args) {
            new NativeMethodExample().nativeMethod();
        }
    }
    

垃圾回收机制

JVM 的垃圾回收机制负责自动管理内存,回收不再使用的对象。以下是几种常见的垃圾回收器和算法:

  1. 垃圾收集器(Garbage Collectors)

    • Serial 垃圾收集器:单线程收集器,适用于单线程环境或小型应用。
    • Parallel 垃圾收集器(Parallel GC):多线程收集器,适用于多线程环境,能够利用多核 CPU 提高垃圾回收效率。
    • CMS(Concurrent Mark-Sweep)收集器:并发收集器,减少了垃圾回收时的停顿时间,适用于需要较高响应速度的应用。
    • G1(Garbage First)收集器:面向服务器端应用,能够更好地控制垃圾回收的停顿时间,适用于大内存、多处理器环境。
  2. 垃圾回收算法(Garbage Collection Algorithms)

    • 标记-清除算法(Mark-Sweep):先标记出所有存活对象,然后清除未被标记的对象。缺点是会产生内存碎片。
    • 复制算法(Copying):将存活对象复制到新空间,然后清除旧空间的所有对象。适用于新生代垃圾回收,效率高,但需要额外的内存空间。
    • 标记-压缩算法(Mark-Compact):先标记出所有存活对象,然后将存活对象压缩到内存的一端,清除未被标记的对象。解决了内存碎片问题,适用于老年代垃圾回收。
    • 分代收集算法(Generational Collection):将堆分为新生代和老年代,新生代对象回收频率高,老年代对象回收频率低。结合复制算法和标记-压缩算法,提高垃圾回收效率。

如何选择垃圾收集器

选择合适的垃圾收集器需要根据具体应用的需求进行权衡:

  • Serial GC:适用于单线程环境或小型应用,垃圾回收时会暂停所有应用线程,适合不需要频繁交互的小应用。
  • Parallel GC:适用于多线程环境,可以利用多核 CPU 提高垃圾回收效率,但在垃圾回收期间也会暂停所有应用线程。
  • CMS GC:适用于需要低停顿时间的应用,如交互性强的服务,垃圾回收过程中大部分工作与应用线程并发执行。
  • G1 GC:适用于大内存、多处理器的服务器端应用,能够更好地控制垃圾回收的停顿时间。
public class GCExample {
    public static void main(String[] args) {
        // 创建大量对象以触发垃圾回收
        for (int i = 0; i < 1_000_000; i++) {
            String temp = new String("Garbage Collection Test " + i);
        }
        // 显示垃圾回收信息
        System.gc();
    }
}

结论

JVM 是 Java 程序运行的核心,深入理解 JVM 的结构和垃圾回收机制有助于优化 Java 应用的性能。不同的垃圾收集器和算法各有优缺点,选择合适的垃圾收集器需要根据具体应用的需求进行权衡。

觉得有用的话可以点点赞 (*/ω\*),支持一下。

如果愿意的话关注一下。会对你有更多的帮助。

每天都会不定时更新哦  >人<  。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DAY22-力扣刷题

1.被围绕的区域 方法一&#xff1a;深度优先搜索 class Solution {int n, m;public void solve(char[][] board) {n board.length;if (n 0) {return;}m board[0].length;for (int i 0; i < n; i) {dfs(board, i, 0);dfs(board, i, m - 1);}for (int i 1; i < m - 1…

项目方案:社会视频资源整合接入汇聚系统解决方案(九)-视频监控汇聚应用案例

目录 一、概述 1.1 应用背景 1.2 总体目标 1.3 设计原则 1.4 设计依据 1.5 术语解释 二、需求分析 2.1 政策分析 2.2 业务分析 2.3 系统需求 三、系统总体设计 3.1设计思路 3.2总体架构 3.3联网技术要求 四、视频整合及汇聚接入 4.1设计概述 4.2社会视频资源分…

5.opencv深浅拷贝

图像处理的复制操作 深浅拷贝 图像复制分成两种&#xff0c;第一种假复制&#xff0c;从原图片选择一部分图片拿出来观察&#xff0c;此时新生成的图片和原图实际上是同一张图片&#xff0c;即浅拷贝 将图片的一部分复制下来&#xff0c;放到新的内存中&#xff0c;即两张完全…

AI视频教程下载-使用ChatGPT成为全栈JavaScript开发者

学习使用Express JS和React JS进行全栈JavaScript开发 ChatGPT Express JS MongoDB React JS Tailwind 解锁全栈网页开发的世界&#xff0c;我们为初学者和中级学习者设计了全面的课程。在这段沉浸式的旅程中&#xff0c;你将深入前端和后端开发的基本概念&#xff0c;为自…

【DataSophon】DataSophon1.2.1 ranger usersync整合

目录 一、简介 二、实现步骤 2.1 ranger-usersync包下载编译 2.2 构建压缩包 2.3 编辑元数据文件 2.4 修改源码 三、重新安装 一、简介 如下是DDP1.2.1默认有的rangerAdmin&#xff0c; 我们需要将rangerusersync整合进来 ,实现将Linux机器上的用户和组信息同步到Ranger…

【Linux】线程(轻量级进程)

目录 一、线程概念 二、线程特性 2.1 进程更加轻量化 2.2 线程的优点 2.3 线程的缺点 2.4 线程的异常 2.5 线程用途 三、进程和线程 四、线程控制 4.1 包含线程的编译链接 4.2 创建线程 4.3 获得线程自身的ID 4.4 线程终止 4.5 线程等待 4.6 线程分离 4.6 线程…

Java数据结构9-排序

1. 排序的概念及引用 1.1 排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录…

【Java】垃圾回收学习笔记(一):Root Search 根可达算法+垃圾回收的起点

文章目录 1. 引用计数法优点缺点 2. 可达性分析 Root Search2.1 那些对象是GC Roots2.2 引用的分类2.3 回收方法区 3. 实现细节3.1 GC的起点&#xff1a;节点枚举OopMap&#xff1a;帮助高效的根节点枚举 3.2 何时开始GC&#xff1a;安全点与安全区域如何选取安全点如何让程序进…

在mac下 Vue2和Vue3并存 全局Vue2环境创建Vue3新项目(Vue cli2和Vue cli4)

全局安装vue2 npm install vue-cli -g自行在任意位置创建一个文件夹vue3&#xff0c;局部安装vue3,注意不要带-g npm install vue/cli安装完成后&#xff0c;进入目录&#xff0c;修改vue为vue3 找到vue3/node-moudles/.bin/vue&#xff0c;把vue改成vue3。 对环境变量进行配置…

web安全基础名词概念

本节内容根据小迪安全讲解制作 第一天 域名&#xff1a; 1.1什么是域名&#xff1f; 网域名称(英语&#xff1a;Domain Name&#xff0c;简称&#xff1a;Domain)&#xff0c;简称域名、网域&#xff0c;是由一串用点分隔的字符组成的互联网上某一台计算机或计算机组的名称&a…

java核心-泛型

目录 概述什么是泛型分类泛型类泛型接口泛型方法 泛型通配符分类 泛型类型擦除分类无限制类型擦除有限制类型擦除 问题需求第一种第二种 概述 了解泛型有利于学习 jdk 、中间件的源码&#xff0c;提升代码抽象能力&#xff0c;封装通用性更强的组件。 什么是泛型 在定义类、接…

存储过程编程-创建(CREATE PROCEDURE)、执行(EXEC)、删除(DROP PROCEDURE)

一、定义 1、存储过程是在SQL服务器上存储的已经编译过的SQL语句组。 2、存储过程分为三类&#xff1a;系统提供的存储过程、用户定义的存储过程和扩展存储过程 &#xff08;1&#xff09;系统提供的存储过程&#xff1a;在安装SQL Server时&#xff0c;系统创建了很多系统存…

Kafka(一)基础介绍

一&#xff0c;Kafka集群 一个典型的 Kafka 体系架构包括若Producer、Broker、Consumer&#xff0c;以及一个ZooKeeper集群&#xff0c;如图所示。 ZooKeeper&#xff1a;Kafka负责集群元数据的管理、控制器的选举等操作的&#xff1b; Producer&#xff1a;将消息发送到Broker…

MySQL事务隔离

MySQL事务隔离 前言锁共享锁&#xff08;Shared Lock&#xff09;排他锁&#xff08;Exclusive Lock&#xff09;行级锁&#xff08;Row-Level Lock&#xff09;表级锁&#xff08;Table-Level Lock&#xff09;快照读和当前读查看锁 事务事务的四个特性事务的并发问题事务的隔…

Chrome 127内置AI大模型攻略

Chrome 127 集成Gemini:本地AI功能 Google将Gemini大模型整合进Chrome浏览器,带来全新免费的本地AI体验: 完全免费、无限制使用支持离线运行,摆脱网络依赖功能涵盖图像识别、自然语言处理、智能推荐等中国大陆需要借助魔法,懂都懂。 安装部署步骤: 1. Chrome V127 dev …

golang验证Etherscan上的智能合约

文章目录 golang验证Etherscan上的智能合约为什么要验证智能合约如何使用golang去验证合约获取EtherscanAPI密钥Verify Source Code接口Check Source Code Verification Status接口演示示例及注意事项网络问题无法调用Etherscan接口&#xff08;最重要的步骤&#xff09; golan…

YoloV9改进策略:Block改进|轻量实时的重参数结构|最新改进|即插即用(全网首发)

摘要 本文使用重参数的Block替换YoloV9中的RepNBottleneck&#xff0c;GFLOPs从239降到了227&#xff1b;同时&#xff0c;map50从0.989涨到了0.99&#xff08;重参数后的结果&#xff09;。 改进方法简单&#xff0c;只做简单的替换就行&#xff0c;即插即用&#xff0c;非常…

保健品商城小程序模板源码

保健品商城小程序模板源码 简洁通用的保健品&#xff0c;健康生活&#xff0c;零售商品&#xff0c;电子商务微信小程序前端模板下载。包含&#xff1a;主页、购物车、客服、个人中心、我的订单、商品详情、我的钱包、设置等等。 保健品商城小程序模板源码

程序员如何做好需求判断?

1. 导语 本文作为2024上半年核心思考之二。 通过他人经验传导、个人实践、广泛阅读书籍(方法论类、企业经营类、传记类、财务类&#xff0c;具体书单附文末)&#xff0c;学会基于更高阶的经营者视角来做好业务需求判断。本文思路如下&#xff1a; 首先&#xff0c;抛一个灵魂问…

【server】springboot 整合 redis

1、redis 使用模式 1.1 单机模式 1.1.1 编译安装方式 1.1.1.1 下载 Redis的安装非常简单&#xff0c;到Redis的官网&#xff08;Downloads - Redis&#xff09;&#xff0c;下载对应的版本&#xff0c;简单几个命令安装即可。 1.1.1.2 编译安装 tar xzf redis-stable.tar.…