JAVA类装载器classloader和命名空间namespace

ClassLoader 隔离性的基石是namespace,证明给你看 汉化叫命名空间(我个人其实更喜欢汉化为名字空间),命名空间由该加载器及所有父类加载器所加载的类组成。,加载不到(不在当前类加载器的类资源管辖范围),如果要使用这个类,必须指定一个能够加载这个类的加载器去加载,而怎么获取这个加载器是个问题。程序都是在线程中执行,那么从线程的上下文中去拿最合理,所以就诞生了线程上下文类加载器,这中场景下加载器就得采用。不同则管辖范围不同,并通过委派执行类加载来保障这种分治能力,进而达到了类资源的隔离性。加载插件中的类,不会对宿主应用中的类产生污染。加载程序中编写的类。 阅读详情

JAVA类装载器classloader和命名空间namespace

  JAVA虚拟机通过装载、连接和初始化一个JAVA类型,使该类型可以被正在运行的JAVA程序所使用。其中,装载就是把二进制形式的JAVA类型读入JAVA虚拟机中。连接就是把这种已经读入虚拟机的二进制形式的类型数据合并到虚拟机的运行时状态中去。连接阶段分为三个步骤-验证、准备和解析。验证确保了JAVA类型数据格式正确并适于JAVA虚拟机使用。准备负责为该类分配它所需的内存,比如为它的类变量分配内存。解析把常量池中的符号引用转换为直接引用,如内存地址指针。在初始化期间,激活类的静态变量的初始化代码和静态代码块。
  装载步骤的最终产品是一个被装载类型的Class类的实例对象,它成为JAVA程序与内部数据结构之间的接口。对于每一个被装载的类型,虚拟机都会相应地为它创建一个Class类的实例。

1 类装载器的安全作用

  JAVA类装载器在JAVA安全体系结构中起着最关重要的作用,是JAVA安全沙箱的第一道防线。类装载器体系结构在三个方面对JAVA的沙箱起作用:
1) 它防止恶意代码去干涉善意的代码
2) 它守护了被信任的类库的边界
3) 它将代码归入某类(称为保护域),该类确定了代码可以进行哪些操作。
类装载器体系结构可以防止恶意代码去干涉善意的代码,这是通过为不同的类装载器装入的类提供不同的命名空间来实现的。

2双亲委派模型

  JAVA虚拟机规范定义了两种类型的类装载器-启动类装载器和用户自定义类装载器,启动类装载器是JAVA虚拟机实现的一部分,通过继承ClassLoader类,用户可以创建自定义的类装载器来完成特定要求的加载。JAVA虚拟机已经创建了2个自定义类装载器-扩展类装载器和系统类装载器。
每一个用户自定义的类装载器在创建时被分配一个“双亲”parent类装载器。如果没有显示地传递一个双亲类装载器给用户自定义的类装载器的构造方法,系统类装载器就默认被指定为双亲。如果传递到构造方法的是一个已有的用户自定义类装载器的引用,该用户自定义类装载器就作为双亲;如果向构造方法传递了null,启动类装载器就是双亲。
启动类装载器Bootstrap Classloader:它是JAVA虚拟机实现的一部分,是c/c++实现的,它没有双亲。启动类装载器装载JAVA核心库代码。
扩展类装载器Extension Classloader:继承自URLClassLoader,初始化向构造方法传递了null,所以双亲是Bootstrap Classloaser。它从java.ext.dirs扩展目录中装载代码。
系统类装载器Application Classloader:继承自URLClassLoader,双亲是Extension Classloaser。它从CLASSPATH路径中装载应用程序代码。
其中,网络类装载器URLClassLoader是JAVA库提供的一个类装载器,用来从网络其他位置装载类。

双亲孩子类装载器委派链


  在双亲委派模型下,当一个装载器被请求装载某个类时,它首先委托自己的双亲parent去装载,若parent能装载,则返回这个类所对应的Class对象,若parent不能装载,则由parent的请求者去装载。

现在假设要求Cindy去装载一个名为java.io.FileReader的类型。Cindy第一件事情就是去找Mom来装载那个类型;Mom所做的第一件事情就是去找Grandma来装载那个类型;而Grandma首先去找启动类装载器去装载。在这个例子中,启动类装载器可以装载那个类型,它就返回代表java.io.FileReader的Class实例给Grandma。Grandma传递该Class的引用 Mom,Mom再回传给Cindy,Cindy返回给程序。

 

  在此模型下,启动类装载器可以抢在扩展类装载器之前去装载类,而扩展类装载器可以抢在系统类装载器之前去装载那个类,系统类装载器又可以抢在网络类装载器之前去装载它。这样,使用双亲-孩子委派链的方式,启动类装载器会在最可信的类库-核心JAVA API-中首先检查每个被装载的类型,然后,才依次到扩展路径、系统类路径中检查被装载的类型文件。用这种方法,类装载器的体系结构就可以防止不可靠的代码用它们自己的版本来替代可以信任的类。

3命名空间

  由不同的类装载器装载的类将被放在虚拟机内部的不同命名空间。命名空间由一系列唯一的名称组成,每一个被装载的类有一个名字。JAVA虚拟机为每一个类装载器维护一个名字空间。例如,一旦JAVA虚拟机将一个名为Volcano的类装入一个特定的命名空间,它就不能再装载名为Valcano的其他类到相同的命名空间了。可以把多个Valcano类装入一个JAVA虚拟机中,因为可以通过创建多个类装载器从而在一个JAVA应用程序中创建多个命名空间。
1) 
初始类装载器/ 定义类装载器

命名空间有助于安全的实现,因为你可以有效地在装入了不同命名空间的类之间设置一个防护罩。在JAVA虚拟机中,在同一个命名空间内的类可以直接进行交互,而不同的命名空间中的类甚至不能觉察彼此的存在,除非显示地提供了允许它们进行交互的机制,如获取Class对象的引用后使用反射来访问。

  如果要求某个类装载器去装载一个类型,但是却返回了其他类装载器装载的类型,这种装载器被称为是那个类型的初始类装载器 ;而实际装载那个类型的类装载器被称为该类型的定义类装载器 。任何被要求装载类型,并且能够返回Class实例的引用代表这个类型的类装载器,都是这个类型的初始类装载器。在上面的一个例子中,java.io.FileReader定义类装载器是启动类装载器,Cindy、Mom、Grandma、启动类装载器都是初始类装载器。

  虚拟机会为每一个类装载器维护一张列表,列表中是已经被请求过的类型的名字。这些列表包含了每一个类装载器被标记为初始类装载器的类型,它们代表了每一个类装载器的命名空间。虚拟机总是会在调用loadClass()之前检查这个内部列表,如果这个类装载器已经被标记为是这个具有该全限定名的类型的初始类装载器,就会返回表示这个类型的Class实例,这样,虚拟机永远不会自动在同一个用户自定义类装载器上调用同一个名字的类型两次。

2) 命名空间的类型共享

  前面提到过只有同一个命名空间内的类才可以直接进行交互,但是我们经常在由用户自定义类装载器定义的类型中直接使用JAVA API类,这不是矛盾了吗?这是类型共享 原因-如果某个类装载器把类型装载的任务委派给另外一个类装载器,而后者定义了这个类型,那么被委派的类装载器装载的这个类型,在所有被标记为该类型的初始类装载器的命名空间中共享。

例如上面的例子中,Cindy可以共享Mon、Grandma、启动类装载器的命名空间中的类型,Kenny也可以共享 Mon、Grandma、启动类装载器的 命名空间中的 类型,但是Cindy和Kenny的命名空间不能共享。

3) 运行时包

  每个类装载器都有自己的命名空间,其中维护着由它装载的类型。所以一个JAVA程序可以多次装载具有同一个全限定名的多个类型。这样一个类型的全限定名就不足以确定在一个JAVA虚拟机中的唯一性。因此,当多个类装载器都装载了同名的类型时,为了唯一表示该类型,还要在类型名称前加上装载该类型的类装载器来表示-[classloader class]。

  在允许两个类型之间对包内可见的成员进行访问前,虚拟机不但要确定这个两个类型属于同一个包,还必须确认它们属于同一个运行时包-它们必须有同一个类装载器装载的。这样,java.lang.Virus和来自核心的java.lang的类不属于同一个运行时包,java.lang.Virus就不能访问JAVA API的java.lang包中的包内可见的成员。

4自定义类装载器

  JAVA类型要么由启动类装载器装载,要么通过用户自定义的类装载器装载。启动类装载器是虚拟机实现的一部分,它以与实现无关的方式装载类型,JAVA提供了抽象类java.lang.ClassLoader,用户自定义的类装载器是类ClassLoader的子类实例,它以定制的方式装载类。所有用户自定义类装载器都实例化自ClassLoader的子类。

下面提供一个简单的用户自定义类装载器。

 

 

输出结果:

valcanoClass1 classloaer = UserDefinedClassLoader@1fb8ee3
valcanoClass2 classloaer = java.net.URLClassLoader@14318bb
valcanoClass1  = valcanoClass2 ? false

我们可以看到,有两个不同的Valcano的Class实例被加载到同一个虚拟机中。

另外我们看到Valcano类静态初始化语句没有被执行,意味着类没有被初始化,这是因为JAVA中只有当类被主动使用时类型才会进行初始化。


Android native开发严重问题总结 本文用于总结开发过程中遇到的重要问题分析原因及其解决方案 1、libnativeloader.so" is not accessible for the namespace “classloader-namespace” 原因:安卓高版本中将会限制三方APP访问非NDK公开so库,即不能访问system/lib/lib64下面的私有so库。 两种情况的解决方案: 第一:若是系统system app,该问题的产生原因是app是通过install的,这样不可行,必须将该模块在编译产品后的system/app路径 阅读详情

相关推荐

轻量级的ndk实用程序,可帮助绕过Android N的classloader-namespace限制-Android开发

轻量级ndk实用程序,可帮助绕过Android N的classloader-namespace限制ndk_dlopen轻量级ndk实用程序,可帮助绕过Android N的classloader-namespace限制技术OSR(堆栈替换)支持x86,x86_64,armeabi-v7a(拇指和手臂) ),arm64-v8a

基于命名空间的动态链接—— 隔离 Android 中应用程序和系统的本地库

转载自:https://jackwish.net/namespace-based-dynamic-linking-chn.html 补充谷歌官网文档:https://source.android.com/devices/architecture/vndk/linker-namespace 本文是Namespace based Dynamic Linking - Isolating ...

along 3575

5G移动性管理实战:手把手教你配置NR小区重选参数(附避坑指南)

本文深入解析5G网络移动性管理中的小区重选参数配置实战。通过拆解小区选择与重选的核心机制,结合真实案例,手把手指导如何配置NR小区重选参数,并分享常见避坑指南,帮助工程师优化网络性能,提升用户移动体验。

weixin_29229261的博客 199

Java的类装载器(Class Loader)和命名空间(NameSpace)

摘要 Java的类装载器是Java动态性的核心,本文将向大家简要介绍Java的类装载器,及相关的parent delegation模型,命名空间,运行时包等概念,同时讨论一些在学习中容易混淆的问题。 类装载器的功能及分类 顾名思义,类装载器是用来把类(class)装载进JVM的。JVM规范定义了两种类型的类装载器:启动内装载器(bootstrap)和用户自定义装载器(user-defined class loader)。 bootstrap是JVM自带的类装载器,用来装载核心类库

juniorhope 548

手把手教你用Verilog实现AT24C64的I2C读写(附完整仿真流程)

本文详细介绍了如何使用Verilog HDL设计AT24C64 EEPROM的I2C控制器,并配合ModelSim完成完整的仿真验证流程。内容涵盖I2C协议解析、Verilog状态机设计、AT24C64读写操作实现,以及仿真波形分析和调试技巧,为FPGA开发者提供了一套完整的EEPROM控制解决方案。

3c4x5z6v7b的博客 844

MT4量化交易入门:手把手教你用MQL4编写第一个外汇EA(含完整代码)

本文详细介绍了如何使用MQL4在MT4平台上编写第一个外汇EA,涵盖从开发环境配置到均线交叉策略实现的完整流程。通过手把手教学和完整代码示例,帮助量化交易新手快速掌握外汇自动化交易的核心技术,实现高效的MT4量化交易系统。

mmm90的博客 526

Java类装载器classloader和命名空间namespace

学习Java的同学注意了!!! 学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群,群号码:434987175 我们一起学Java! Java虚拟机通过装...

chuifuhuo6864的博客 409

别再手动调波形了!用STM32G474的HRTIM+DAC生成精密锯齿波,附完整CubeMX配置

本文详细介绍了如何利用STM32G474的高分辨率定时器(HRTIM)和数模转换器(DAC)协同工作,实现高精度锯齿波生成。通过CubeMX配置指南、关键寄存器计算和实践技巧,帮助开发者快速掌握全硬件实现的波形生成方案,显著提升嵌入式系统的波形控制精度和响应速度。

weixin_28716769的博客 246

[转]Java的类装载器(Class Loader)和命名空间(NameSpace)

Java的类装载器(Class Loader)和命名空间(NameSpace)  摘要Java的类装载器是Java动态性的核心,本文将向大家简要介绍Java的类装载器,及相关的parent delegation模型,命名空间,运行时包等概念,同时讨论一些在学习中容易混淆的问题。 类装载器的功能及分类顾名思义,类装载器是用来把类(class)装载进JVM的。JVM规范

在路上 629

Python 爬虫实战:爬取 GitHub 热门项目(星数 / 语言 / 作者)

本文系统介绍了使用Python爬虫技术获取GitHub热门项目数据的完整方案。通过分析GitHub Trending页面和官方API两种数据源,详细讲解了HTML解析、JSON数据处理、反爬应对策略等关键技术。采用requests、BeautifulSoup、pandas等工具链,实现了项目信息(名称、星数、语言等)的结构化爬取,并配套数据清洗、统计分析及可视化功能。特别强调遵守GitHub API使用规范,包括Token认证、请求频率控制等合规要求。该方案为开发者提供了一种高效、合法的数据采集方法,适用于

2503_91057718的博客 2342

【错误解决】本地计算机上的mysql服务启动停止后,某些服务在未由其他服务或程序使用时将自动停止

转载请注明出处:http://blog.youkuaiyun.com/qq_26525215 本文源自【大学之旅_谙忆的博客】 在启动mysql服务时出现该错误: 本地计算机上的mysql服务启动停止后,某些服务在未由其他服务或程序使用时将自动停止。mysql 版本 5.7.14 系统 win 7后来经过一系列的百度,谷歌,总算是解决了。首先,你需要把原来的服务删除:mysqld --remove mysq

谙忆-陈浩翔 12万+
上一篇: JAVA finally字句的异常丢失和返回值覆盖解析
下一篇: JAVA String对象和字符串常量的关系解析
飞天金刚
博客等级 码龄17年 35粉丝 15原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值