JVM简单学习

news2024/10/1 19:24:48

jvm与字节码

jvm只需关注字节码文件
在这里插入图片描述
jvm由哪些部分构成
在这里插入图片描述
1.类加载子系统,将磁盘中的字节码文件加载到方法区的内存空间中
在这里插入图片描述
类加载器分两种:引导类加载器是jvm底层中用C和C++语言写的

在这里插入图片描述
各个默认的类加载器的不同区别在于 各自默认负责要加载的类的目录不一样
比如
BootStrapClassLoader:负责jre/lib 目录下
ExtClassLoader:负责jre/lib/ext 目录下
AppClassLoader:负责 classpath目录下

什么是双亲委派 和 双亲委派的两大作用

  1. 避免类的重复加载
  2. 防止核心API被篡改

什么是双亲委派机制

双亲委派机制(Parent Delegation Mechanism)是Java中的一种类加载机制。在Java中,类加载器负责加载类的字节码并创建对应的Class对象。双亲委派机制是指当一个类加载器收到类加载请求时,它会先将该请求委派给它的父类加载器去尝试加载。只有当父类加载器无法加载该类时,子类加载器才会尝试加载。

这种机制的设计目的是为了保证类的加载是有序的,避免重复加载同一个类。Java中的类加载器形成了一个层次结构,根加载器(Bootstrap ClassLoader)位于最顶层,它负责加载Java核心类库。其他加载器如扩展类加载器(Extension ClassLoader)和应用程序类加载器(Application ClassLoader)都有各自的加载范围和职责。通过双亲委派机制,可以确保类在被加载时,先从上层的加载器开始查找,逐级向下,直到找到所需的类或者无法找到为止。

这种机制的好处是可以避免类的重复加载,提高了类加载的效率和安全性。同时,它也为Java提供了一种扩展机制,允许开发人员自定义类加载器,实现特定的加载策略。

双亲委派机制的原理

双亲委派机制是Java中的一种类加载机制。其原理如下:

  1. 当Java程序需要加载一个类时,首先会委托给当前类加载器的父类加载器进行加载。

  2. 父类加载器会按照相同的方式尝试加载该类。如果父类加载器能够成功加载该类,则加载过程结束。

  3. 如果父类加载器无法加载该类,则会将加载请求再次委托给它的父类加载器,直到达到顶层的引导类加载器。

  4. 引导类加载器是Java虚拟机内置的类加载器,它负责加载核心类库,如java.lang包下的类。

  5. 如果引导类加载器也无法加载该类,则会回到初始的类加载器,尝试使用自身的加载机制加载该类。

  6. 如果自身的加载机制仍然无法加载该类,则会抛出ClassNotFoundException异常。

通过这种双亲委派的机制,Java实现了类加载的层次结构。它可以确保类的加载是有序的,避免了重复加载和类的冲突。同时,它也提供了一种安全机制,防止恶意代码的加载和执行。

主要实现在ClassLoader里的loadClass方法

双亲委派主要体现在 ClassLoader#loadClass() 方法中:

PS:每个 ClassLoader 都有如下三个基础方法:

  • loadClass()
    • 入口,定义了 加载/寻找 Class 的策略。比如双亲委派,或者其他形式
    • 调用 findClass() 读入 class 文件,并生成 Class 对象
  • findClass()
    • 根据 class 名,在当前 ClassLoader 能处理路径中查找,如果能找到就将 class 文件读入
    • 调用 defineClass 生成 Class 对象
  • defineClass()
    • native 方法
    • 将字节数组生成 Class 对象
// resolve = false 不进行解析
protected Class<?> loadClass(String name, boolean resolve) 
        throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {
            // 查看该类是否被加载过
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                try {
                    // 获取当前类父类的加载器
                    if (parent != null) {
                        // 使用父类的加载器加载!!!
                        // 递归
                        c = parent.loadClass(name, false);
                    } else {
                        // 如果 parent 为 null,说明父类加载器为引导类加载器
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                }
				
                // 当前类的加载器父类加载器未加载此类 or 当前类的加载器未加载此类
                if (c == null) {
                    long t1 = System.nanoTime();
                    // 调用当前 Classloader 的 findClass
                    // 注:可能当前 classloader 无法处理要加载的这个类的路径,这时返回 null
                    c = findClass(name);

                    // this is the defining class loader; record the stats
                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    sun.misc.PerfCounter.getFindClasses().increment();
                }
            }
            // 根据入参决定是否解析
            if (resolve) { 
                resolveClass(c);
            }
            return c;
        }
}

如何自定义类加载器,下面是一个自定义 ClassLoader 示例,直接继承 ClassLoader 类,然后重写 findClass 方法就行了(采用双亲委派)

public class MyClassLoader extends ClassLoader{
	
    // 指定的要加载 class 文件的目录
    private File classPathFile;  
    
    public MyClassLoader(String absolutePath) {
        this.classPathFile = new File(absolutePath);
    }

    @Override
    // 根据类名将指定类加载进 JVM
    // 注:该 class 必修在指定的 absolutePath 下
    protected Class<?> findClass(String name) throws ClassNotFoundException {

        // 拼接全类名
        String className = MyClassLoader.class.getPackage().getName() + "." + name;
        if(classPathFile  != null){
            // 根据绝对路径,以及 class 文件名,拿到 class 文件
            // 注意全类名的情况 
            File classFile = new File(classPathFile,name.replaceAll("\\.","/") + ".class");
            // 如果 class 文件存在
            if(classFile.exists()){

                // 将 class 文件读入内存,暂存到一个字节数组中
                FileInputStream in = null;
                ByteArrayOutputStream out = null;
                try{
                    in = new FileInputStream(classFile);
                    out = new ByteArrayOutputStream();
                    byte [] buff = new byte[1024];
                    int len;
                    while ((len = in.read(buff)) != -1){
                        out.write(buff,0,len);
                    }

                    // 构造类的 Class 对象!!!
                    // 注:defineClass() 是一个 native 方法
                    return defineClass(className, out.toByteArray(), 0, out.size());
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}

运行时数据区

在这里插入图片描述

程序计数器

在这里插入图片描述

Java方法栈

一个方法对应一个栈帧,方法内有其他方法就会依次入栈,执行完的方法对应的栈帧会出栈

在这里插入图片描述
OOM是内存不够, StackOverflowError 是方法调用层次太多
在这里插入图片描述

栈帧

局部变量表

slot 代表各个方法内的局部变量
在这里插入图片描述

操作数栈

在这里插入图片描述

在这里插入图片描述
执行步骤

  • 10 压入操作数栈
  • 将 10 放入局部变量表 2
  • 将20 压入操作数栈
  • 将20 放入局部变量表2
  • iload1 将 局部变量表1放入操作数栈 iload2 将 局部变量表2放入操作数栈
  • iadd 操作数栈中相加,得到的值放入局部变量3
    在这里插入图片描述

本地方法栈

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
Java对象在各个区域的流转情况

对象首先来到Eden区,Eden满了后进行一次GC,没被清理的对象来到S0区计数加一,Eden迎接新对象,每次GC存活对象计数加一,计数达到阈值进入老年代,如果有大对象(文件上传对象)S0和S1放不下直接进入老年代
在这里插入图片描述

各个GC的区别

老年代只有一个CMS专门回收
在这里插入图片描述

为什么要进行垃圾回收

在这里插入图片描述

垃圾标记阶段,如何标记垃圾

在这里插入图片描述

引用计数法

在这里插入图片描述

可达性分析法

在这里插入图片描述

GCRoots包括哪些

在这里插入图片描述
虚拟机栈和本地方法栈中的方法参数和局部变量存储的是对象的地址值

GC算法

标记清除算法

在这里插入图片描述

  • 缺点
    • 效率不高
    • 会产生内存碎片
  • 优点
    • 简单
复制算法

利用空间换时间,适合垃圾对象比较多,非垃圾对象少,这样复制成本就低效率就高。
新生代适合用复制算法,因为对象朝生夕死

在这里插入图片描述
在这里插入图片描述

标记整理算法

在这里插入图片描述
在这里插入图片描述

算法总结

在这里插入图片描述

一种GC算法的使用理念

算法按需使用,用到最适合他的地方

在这里插入图片描述

常见的垃圾收集器

在这里插入图片描述

CMS 如何工作

在这里插入图片描述

并发标记清除算法,特点低暂停,STW时间短,执行过程长,工作线程暂停时间短影响小,所以用户体验好,但是吞吐量变低
在这里插入图片描述

  • 阶段一 初始标记:

    • STW暂停所有工作线程
    • 标记出GCRoots能直接可达对象(以GCRoots为起点的第一层引用对象,不再向下标记)
    • 一旦标记,就回复工作线程继续执行
    • 这个阶段比较短,所以STW时间短
  • 阶段二 并发标记(最费时的阶段,但是不STW不影响工作线程工作):
    在这里插入图片描述
    因为工作线程也在运行中,标记垃圾可能会有误差,因为程序在运行就有可能产生垃圾对象,但是误差不大

  • 阶段三和阶段四 重新标记短暂STW后并发清理
    在这里插入图片描述

CMS存在的问题

在这里插入图片描述

G1是如何工作的

在这里插入图片描述

G1垃圾回收器下,堆空间不再是其他回收器那样的各个代之间层次分明,而是把堆空间分成2048个Region进行管理,各个代空间逻辑上连续,但是物理上不再连续

在这里插入图片描述
G1的初始标记和并发标记与CMS相同

在这里插入图片描述

G1和CMS最大区别在最后一步,CMS是清除算法,G1是复制算法,复制到空闲的region
在这里插入图片描述

G1的筛选回收

可以指定GC的STW停顿时间,CMS的STW时间是不确定的,相较于CMS的清除算法,G1是把需要清理的Region中的非垃圾对象复制到空闲的Region区域

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

web前端游戏项目-辨色大比拼【附源码】

web前端游戏项目-辨色大比拼【附源码】 《辨色大比拼》是一个旨在测试和提升玩家颜色识别能力的在线游戏。在游戏中&#xff0c;玩家将通过辨识颜色来解谜并推进游戏进程。辨色大比拼也是一个寓教于乐的游戏&#xff0c;它不仅提供了一个有趣的辨色挑战&#xff0c;还能帮助玩…

通过 Higress Wasm 插件 3 倍性能实现 Spring-cloud-gateway 功能

作者&#xff1a;韦鑫&#xff0c;Higress Committer&#xff0c;来自南京航空航天大学分布式系统实验室 导读&#xff1a;本文将和大家一同回顾 Spring Cloud Gateway 是如何满足 HTTP 请求/响应转换需求场景的&#xff0c;并为大家介绍在这种场景下使用 Higress 云原生网关的…

【Linux】Linux常见指令解析上

目录 1. 前言2. ls指令3. pwd指令4. cd指令3.1 cd常见快捷指令 4. touch指令5. mkdir指令6. rmdir指令 && rm指令 &#xff08;重要&#xff09;6.1 rmdir指令6.2 rm指令 7. man指令 1. 前言 这篇文章我们将详细介绍一下Linux下常见的基本指令。 2. ls指令 语法: ls [选…

掌握函数式组件:迈向现代化前端开发的关键步骤(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

精通推荐算法1:为什么需要推荐系统(系列文章,建议收藏)

作者简介&#xff1a; 腾讯算法研究员。硕士毕业于中国科学院大学。在阿里和腾讯工作多年&#xff0c;拥有丰富的搜索和推荐算法经验。CSDN博客专家&#xff0c;原创文章100篇。发表专利15个&#xff0c;其中已授权6个。 1 概述 随着互联网的大力发展&#xff0c;用户规模和…

操作无法完成(错误 0x000006ba),Windows 11 PDF打印机无法使用解决办法

操作无法完成(错误 0x000006ba)&#xff0c;Windows 11 PDF打印机无法使用解决办法 解决方式一 先重启一次电脑&#xff0c;看看是否可以解决问题。 解决方式二 重新启动 Printer Spooler 服务

降本后如何有效增效

在当今竞争激烈的商业环境中&#xff0c;“勒紧裤腰带”式的求生存谋发展&#xff0c;已成为更多成长型企业常态化的战略方向之一了。然而&#xff0c;如何在有限的资源成本下释放更多的效能&#xff1f;降本策略是否会影响组织活力造成得不偿失的结果&#xff1f;如果降本之后…

Maya python清除命名空间

问题描述&#xff1a; Maya命名空间可能存在嵌套。 如上&#xff0c;直接删除 :female_actor02会出现异常。 因此需要先删除子命名空间&#xff0c;再删除父命名空间。 解决方法&#xff1a; def remove_namespace_node(namespace_name, ns_parent":"):""…

解决虚拟机卡顿、卡死、待机后不动的情况(真实有效

本人环境&#xff1a; VM workstation 17.5 ubuntu 22.04 虚拟机配置&#xff1a;4核 4g issue&#xff1a; 出现开机卡死不动运行一段时间&#xff0c;可能半小时不到&#xff0c;就页面卡死不动经常需要关机重启才解决&#xff0c;可能没有解决 1.配置虚拟化引擎 这一步我称…

旅游品牌网站搭建的作用是什么

我国旅游业规模非常高&#xff0c;各地大小旅游景区也是非常多&#xff0c;尤其节假日更是可以达到峰值&#xff0c;无论周边游还是外地游对所要去的景区&#xff0c;消费者总是需要来回了解很多&#xff0c;浏览器查或旅行社咨询等。 对旅游企业而言&#xff0c;传统线下方式…

css 实现满屏升空的气球动画

最终实现效果 demo放在最后了。。。。 问题一 怎么实现满屏气球&#xff1f;简单理解就是多个气球的合并&#xff0c;难道要写多个盒子吗&#xff1f;确实是这样子&#xff0c;但可以有更好的办法&#xff0c;其实就是通过原生操作多个盒子生成&#xff0c;所以只需要实现一个…

【JavaWeb学习笔记】13 - JSP浏览器渲染技术

项目代码 https://github.com/yinhai1114/JavaWeb_LearningCode/tree/main/jsp 目录 项目代码 JSP 一、JSP引入 1.JSP现状 2.为什么需要JSP 二、JSP基本原理及使用 1.基本介绍 2.快速入门 ​编辑 3.JSP运行原理 4.page指令 三、JSP三种常用的脚本 1.声明脚本基本语…

做到这两条,破解35岁中年危机

最近我在看吴军老师的《富足》这本书&#xff0c;其中有一篇文章讲的是如何破解35岁中年危机&#xff0c;我觉得讲清楚了这个问题的本质&#xff0c;我在这里分享给你&#xff0c;以下内容大部分摘抄自《破解35岁中年危机》一章。 35岁中年危机的原因 35岁中年危机的说法好像…

nodejs微信小程序+python+PHP计算机网络在线考试系统-计算机毕业设计推荐

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

04_线性表

线性表 顺序表顺序表的实现顺序表的遍历顺序表的容量可变顺序表的时间复杂度java中ArrayList实现 链表单向链表单向链表API设计java中LinkedList实现 链表的复杂度分析链表反转快慢指针中间值问题单向链表是否有环问题有环链表入口问题 循环链表约瑟夫问题 栈栈概述生活中的栈计…

nuxt打包占用磁盘IO

目录 前言排除过程 前言 jenkins运行打包&#xff0c;总是要卡一段时间&#xff0c;磁盘IO很高。我手动执行后的确发现了这个问题&#xff0c;如下图所示。 排除过程 我的方案很原始&#xff0c;利用git恢复到以前的版本&#xff0c;抽检&#xff0c;搞了差不多两个小时&am…

简单的喷淋实验--嵌入式实训

目录 喷淋实验--嵌入式实训 1.MQTT通信原理 2.MQTT库的移植 3.代码流程 运行视频如下: 喷淋实验--嵌入式实训 1.MQTT通信原理 MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级的发布/订阅消息传输协议&#xff0c;旨在提供可靠、高效的通信…

基于Java SSM框架实现教学质量评价评教系统项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架实现教学质量评价评教系统演示 摘要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;教学质量评价系统当然也不能排除在外。教学质量评价系统是以实际运用为…

Git本地仓库命令补充

说明&#xff1a;之前对Git本地仓库的基础使用总结过一篇笔记&#xff0c;Git本地仓库使用&#xff0c;本文对Git的一些基础命令进行补充。 一步提交 通常&#xff0c;我们本地仓库使用Git&#xff0c;文件都需要先 add&#xff0c;将文件从工作区加入到暂存区&#xff0c;然…

MOSFET管驱动设计细节,波形分析

MOSFET管驱动设计细节,波形分析 Chapter1 MOSFET管驱动设计细节,波形分析MOSFET驱动芯片的内部结构MOS驱动电路设计需要注意的地方MOS管驱动电路参考MOS管驱动电路的布线设计常见的MOS管驱动波形高频振铃严重的毁容方波又胖又圆的肥猪波打肿脸充正弦的生于方波他们家的三角波大…