浅谈JVM(一) ClassLoader的双亲委派和沙箱机制

本文详细介绍了Java虚拟机(JVM)的内部结构及工作原理,包括运行时数据区的五大组成部分、类加载器的功能及其类型、双亲委派模型的工作流程以及沙箱机制如何确保Java的安全运行。

JVM(Java Virtual Machine)   java虚拟机 

JVM运行在操作系统之上,与计算机硬件没有交互

JVM整体运行流程需要用到的资源 可以说分以下标红的5部分组成

class files 被java命令运行 将类信息通过类装载器(ClassLoader)加载并初始化生成 Class模版放入运行时数据区(Runtime Data Area)

运行时数据区包括 5部分 : 方法区 和 堆(线程公有)   java栈和本地方法栈和程序计数器(线程私有)

执行引擎(Execution Engine)负责从java栈中取得命令解释成操作系统可识别命令,并交给操作系统执行

本地接口(Native Interface)和本地方法库  融合了别的编程语言(C/C++)为java所用,java诞生时c和c++处于统治地位,

java或多或少会使用c/c++实现一些底层方法(native)方法,于是专门在内存中开辟了一块区域来登记native方法,

在执行引擎执行时加载native libraies,目前这些方法使用越来越少了.

今天总结一部分

ClassLoader

负责加载class文件,class文件在文件开头有特定的文件标示,并且ClassLoader只负责class文件的加载,至于它是否可以运行,则由Execution Engine决定

目前了解4种类加载器:

1.BootstrapClassLoader 启动类加载器

这货是用C++编写的   是最顶层的类装载器,用来加载jre/lib/rt.jar下的类

2.ExtensionClassLoader拓展类加载器

用来加载jre/lib/ext/*.jar的所有类

3.AppClassLoader 应用类加载器

应用类加载器,也叫系统类加载器,用来加载当前应用classpath下的所有类

4.User-Definend 用户自定义的类加载器

继承 java.lang.ClassLoader类实现里面的方法,自定义加载类的方法

双亲委派机制

双亲委派模型的式作过程是:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法完全这个加载请求时,子加载器才会尝试自己去加载。

沙箱机制

沙箱机制是由基于双亲委派机制上 采取的一种JVM的自我保护机制,假设你要写一个java.lang.String 的类,由于双亲委派机制的原理,此请求会先交给Bootstrap试图进行加载,但是Bootstrap在加载类时首先通过包和类名查找rt.jar中有没有该类,有则优先加载rt.jar包中的类,因此就保证了java的运行机制不会被破坏.

<think> 首先,用户的问题是:“我想了解双亲委派机制的描述 请问双亲委派机制的详细描述”。这基于之前的引用内容,包括[^1]、[^2]、[^3]、[^4]。我需要参考这些引用来提供详细描述。 关键引用内容: - 引用[^1]:描述了双亲委派机制的过程:类加载器接收到加载任务时,自底向上查找是否加载过,再由顶向下加载。每个类加载器有父类加载器,启动类加载器没有父类。流程是先检查自己是否加载,如果没有,委派给父类加载器。 - 引用[^2]:解释了为什么设计双亲委派机制:沙箱安全机制(防止篡改核心API),避免类的重复加载(保证类的唯性)。 - 引用[^3]:强调了如果没有双亲委派,可能会导致多个Object类,破坏类的唯程序稳定性。 - 引用[^4]:讨论了打破双亲委派机制的情况,比如Tomcat的JasperLoader用于热加载JSP文件,违背了双亲委派模型。 我的回答需要结构化、清晰,遵循系统级指令: - 所有行内数学表达式用$...$格式(但这里可能不需要数学表达式)。 - 独立公式用$$...$$格式(可能不需要)。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题(在回答结束后)。 - 引用的段落末尾自然地添加引用标识,例如[^1]。 回答结构: 1. 引言:简要介绍双亲委派机制。 2. 详细描述过程:基于引用[^1]。 3. 目的优点:基于引用[^2][^3]。 4. 打破机制的情况:基于引用[^4]简要提及。 5. 总结。 6. 生成相关问题。 确保回答真实可靠:基于提供的引用,不添加额外信息。 详细描述: - 类加载器层次:启动类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)、系统类加载器(System ClassLoader)、自定义类加载器。引用[^1]提到启动类加载器没有父类。 - 加载过程: - 类加载器接收到加载请求。 - 先检查自己是否已加载该类。如果已加载,直接返回。 - 如果未加载,委派给父类加载器。 - 父类加载器重复相同过程:检查自己,委派给其父类。 - 最终到启动类加载器。如果顶层的父类加载器无法加载,才由子类加载器尝试加载。 - 这就是“自底向上查找”(查找是否加载),然后“由顶向下加载”(加载过程)。 - 优点: - 沙箱安全机制:防止用户自定义类覆盖核心类,如java.lang.String。 - 避免重复加载:保证同个类只被加载次,维护类的唯致性。 - 打破机制:在某些场景下,如Tomcat的热加载,使用自定义类加载器直接加载而不委派,以满足特定需求。 在引用时,自然地添加标识,例如在描述的段落末尾加[^1]。 最后,生成相关问题: - 相关问题应基于主题,如双亲委派机制的应用、优缺点、打破机制的例子等。 - 参考之前的示例,生成2-3个问题。 完整回答结构: - 开头:直接回答问题。 - 主体:分点描述过程、优点、打破情况。 - 结束:简要总结。 - 然后:相关问题。 </think> ### 双亲委派机制的详细描述 双亲委派机制是Java类加载过程中的核心机制,用于确保类加载的安全性性。它基于类加载器的层次结构工作,具体过程如下: 1. **类加载器层次结构**: 每个类加载器都有个父类加载器(启动类加载器除外)。Java虚拟机的类加载器通常分为三层: - **启动类加载器(Bootstrap ClassLoader)**:位于顶层,负责加载Java核心库(如java.lang包),没有父类加载器[^1]。 - **扩展类加载器(Extension ClassLoader)**:父类为启动类加载器,加载扩展库(如jre/lib/ext目录下的jar包)。 - **系统类加载器(Application ClassLoader)**:父类为扩展类加载器,加载应用程序类路径(ClassPath)上的类。 此外,开发者可以定义自定义类加载器(如Tomcat的WebAppClassLoader),它们也须遵循父类委托原则[^4]。 2. **加载流程(自底向上查找,由顶向下加载)**: 当个类加载器接收到加载类的请求时,它会执行以下步骤: - 首先,检查自己是否已加载该类。如果已加载,直接返回已加载的类对象(避免重复加载)。 - 如果未加载,它会将加载请求委派给父类加载器(而非自己尝试加载)。 - 父类加载器重复相同过程:检查自身是否加载过,未加载则继续委派给其父类加载器。 - 这个过程直向上传递到启动类加载器(顶层)。如果启动类加载器无法加载该类(如核心库中不存在),加载请求会逐级向下回退: - 扩展类加载器尝试加载。 - 若失败,系统类加载器尝试加载。 - 最后,如果所有父类加载器都无法加载,原始类加载器才会自己尝试加载该类(例如从自定义路径加载)[^1]。 这个过程确保了加载请求总是从顶层向下传递,优先级为启动类加载器 > 扩展类加载器 > 系统类加载器 > 自定义类加载器。 3. **核心目的与优点**: - **沙箱安全机制**:防止恶意代码篡改核心Java类。例如,用户自定义个java.lang.String类,但双亲委派机制会优先由启动类加载器加载标准String类,自定义类不会被加载,从而保护Java核心API的完整性[^2][^3]。 - **避免类的重复加载**:保证同个类在全JVM中只被加载次,维持类的唯性。如果没有此机制,多个类加载器可能加载同名但不同的类,导致程序错误(如多个Object类实例,破坏类型检查系统稳定性)[^2][^3]。 - **稳定性保障**:确保类加载的顺序性致性,防止类冲突,支持JVM的安全运行[^3]。 4. **打破双亲委派机制的情况**: 虽然双亲委派是Java推荐的标准模型,但在某些场景下会被打破。例如: - **热加载需求**:Tomcat容器中的JasperLoader类加载器直接加载已修改的JSP文件(而不委派给父类),实现实时热加载功能。这种行为违背了双亲委派机制,但解决了特定应用需求[^4]。 - **其他场景**:如OSGi框架或自定义类加载器,可能直接加载类以避免父类委托的限制。 总结来说,双亲委派机制通过规范的加载流程层次结构,确保了Java应用的安全性、稳定性与类的唯性。它在大多数标准Java环境中是默认行为,但在特定优化场景下可以被打破以满足动态需求[^1][^2][^3][^4]。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值