class loader的体系结构

本文探讨了Java安全模型中的沙箱概念,并详细解析了类加载器体系结构如何在其中扮演关键角色。文中介绍了primordial类加载器与自定义类加载器的工作原理及它们之间的交互方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

没有看过bill venners的《深入Java虚拟机》,但是看了他写的四部曲中的security and the class loader architecture,感觉受益颇深,建议大家有时间可以去看看原文,本文将对其中的class loader architecture的内容总结一下。

在介绍本文之前,先说一下什么是sandbox,翻译过来就是“沙箱”,在计算机安全中,sandbox指的是一个虚拟的容器,不被信任的程序可以在该容器中安全执行;在软件开发中,sandbox指的是一个在线的环境,该环境在不影响原来系统的前提下,能够测试代码和内容的变化。大家可以参考http://en.wikipedia.org上面关于sandbox的解释,不过该网站被gcd封掉了,可以用代理上。在看英文文章的时候,不明白的术语可以到上边查,挺不错的网站。

相对于sandbox的第一种解释,java的security model能够保护end-user使其不受到untrusted source的侵入。为了达到这个目的java程序提供了一个自定义的sandbox,而java程序运行在这个sandbox之内。java程序在sandbox之内可以做任何事情,但是不能在sandbox边界之外运行任何东西。

class loader体系结构

class loader体系结构在security sandbox中起到重要的作用。在一个虚拟机中可以存在多个的class loader,一个java应用可以用两种类型的class loader。一种是primordial class loader,另外一种是class loader object。primordial class loader是JVM实现的一部分。例如:一个JVM在OS之上利用C来实现,则该primordial class loader是C程序的一部分。primordial class loader用于装载trusted classes,包括Java API的class,通常是从本地硬盘中装载这些class。

JVM认为通过primordial class loader装载的类都是trusted class,而不管这些class是否是Java API的class;而对于从class loader object装载进来的类则需要判断是否安全,默认的是把由class loader object装载进来的class看作是untrusted class。class loader objects是用java编写的,被编译成class文件,然后被虚拟机所装载,最后像初始化其他object一样来进行初始化class loader object。可以利用class loader object在应用运行时刻装载class。

class loader object和primordial class loader的关系参见下图:

 

class loader和name-spaces

在JVM利用这两种class loader装载class的时候,如果被class loader装载的class A引用了其他的class B,则装载class A的class loader也会装载该class B。name-spaces就是一个被某个class loader所加载的类的名字的集合,对于每个class loader,JVM都维持一个与其对应的name-space,在同一个name-space下的类的名字是不能相同的。而可以建立多个class loader来加载同名的class,结果是一个JVM有多个class loader,而在每个class loader对应的name-spaces下有相同的class存在。如果程序不做出显示规定,那么在不同的name-space下的class是不能相互访问的。因此通过name-space可以在由不同的class loader加载的classes之间建立shield,因此说class loader在security sandbox中起到重要作用。

class loader之间的交互

通常情况下,一个class loader object要和其他的class loader交互,至少要和primordial class loader交互。例如:一个java应用利用class loader object加载网络上的class,实现起来可以通过先让该class loader object调用primordial class loader,在trusted classes库(通常是本地的Java API和本地classes)中查找是否存在该class,如果不存在,则会以自定义的方式来加载远程的class。然后在访问这个加载后的远程class时,该class可能存在对一个String类的引用,因此按照该class loader object加载该远程class的方式加载该String类,首先是调用primordial class loader,此时在本地的Java API中找到了该类,则在本地中加载该String类。可能在primordial class loader在加载String类之前,String类已经被加载进来了,则primordial class loader所做的就是返回以前加载的String类。

没想到写这东西这么花时间,在security and the class loader architecture中还介绍了建立security environment及其相关内容,本文将不再提到,大家有时间可以自己去看看,转述的总不如原文深刻。下面给出了一些相关链接:

java's security architecture
http://www.javaworld.com/javaworld/jw-08-1997/jw-08-hood.html

security and the class verifier
http://www.javaworld.com/javaworld/jw-10-1997/jw-10-hood.html

java security:how to install the security manager and customize your security policy
http://www.javaworld.com/javaworld/jw-11-1997/jw-11-hood.html

security and the class loader architecture
http://www.javaworld.com/javaworld/jw-09-1997/jw-09-hood.html

 

### JVM体系结构详解 JVMJava Virtual Machine)是Java程序运行的基础,它是介于Java程序和操作系统之间的中间层。JVM的主要功能是将字节码解释为机器可读的指令,并提供必要的运行时支持。 #### 1. JVM的整体架构 JVM由以下几个核心组件构成[^1]: - **类加载器(Class Loader)** - **运行时数据区(Runtime Data Area)** - **执行引擎(Execution Engine)** 这些组成部分共同协作,使得Java程序能够在不同的平台上无缝运行。 --- #### 2. 类加载器(Class Loader) 类加载器负责动态加载`.class`文件到JVM中。它的主要职责是从磁盘或其他资源中获取字节码,并将其转换为可在JVM中使用的类对象。类加载器分为以下几种类型[^3]: - **启动类加载器(Bootstrap ClassLoader)**: 加载Java的核心库(如`rt.jar`),通常由本地代码实现。 - **扩展类加载器(Extension ClassLoader)**: 负责加载标准扩展库。 - **应用程序类加载器(Application ClassLoader)**: 用户自定义的应用程序类路径下的类都由该加载器加载。 --- #### 3. 运行时数据区(Runtime Data Area) 这是JVM在运行期间用来管理内存的空间,按照用途划分为几个区域: ##### (1)方法区(Method Area) 方法区用于存储已被虚拟机加载的类信息、常量池、静态变量以及即时编译后的代码等。尽管有时被称为“永久代”,但它并不是不可变的——其中的内容也可以被垃圾回收器清理掉,例如无用的类或常量[^4]。 ##### (2)堆(Heap) 堆是最重要的一部分内存分配区域,所有的对象实例都在这里创建。由于堆是所有线程共享的,因此它是垃圾收集的重点关注对象之一。 ##### (3)栈(Stack) 每个线程都有自己的私有栈,保存局部变量表、操作数栈、返回地址以及其他帧数据。每当调用一个新方法时,都会为其创建一个新的栈帧;当方法结束时,对应的栈帧就会被销毁。 ##### (4)PC寄存器(Program Counter Register) 记录当前线程所执行的字节码指令的位置。如果正在执行的是本地方法,则此寄存器为空。 ##### (5)本地方法栈(Native Method Stack) 类似于普通的Java栈,只不过它服务于原生函数调用而非纯Java逻辑处理。 --- #### 4. 执行引擎(Execution Engine) 执行引擎的作用是对字节码进行解析并最终转化为底层硬件能够理解的操作命令。以下是其工作流程的关键环节[^1]: - **解释器(Interpreter):** 将字节码逐条翻译成特定平台上的机器语言立即执行。 - **即时编译器(Just-In-Time Compiler, JIT):** 对频繁被执行的部分热点代码提前完成优化后再交付给CPU运行,从而提升整体性能表现。 两者可以协同合作,在不同场景下发挥各自优势。 --- ### 总结 综上所述,JVM通过精心设计的内部机制实现了跨平台特性的同时还兼顾了高效性和灵活性。无论是从理论层面还是实际应用角度来看,深入掌握JVM原理都是非常有价值的技能点。 ```python # 示例:简单的Java字节码演示如何映射至JVM模型 public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } } ``` 上述代码展示了最基础的Java程序及其背后涉及到了哪些JVM部件参与运作过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值