JVM深入学习笔记六-JVM类加载

简介: <p><span style="font-size:24px"><span style="background-color:rgb(51,255,51)">类加载过程</span></span></p> <p><img src="http://img.blog.csdn.net/20141010160704333?watermark/2/text/aHR0cDovL2Jsb2cuY3Nk

类加载过程


主要分为了 加载->链接(验证->准备->解析)->初始化->使用->卸载这几个阶段。

加载

三件事

1. 通过类的权限定名称来获取定义此类的二进制字节流(可以是文件,网络,数据库,动态等等等等)

2. 把类的结构放在方法区中

3. 创建Class对象作为访问入口

验证

主要包括了字节码验证,元数据验证(这部分在编译期间基本上避免了),类文件格式验证。

准备

包括了内存分配和类变量(static)初始值的设定,以及常量池的写入。

解析

主要是解析符号引用和直接引用,符号引用就是个字面量,直接引用是真正的内存地址。

初始化

就是执行<clinit>()方法的过程

它是 由类变量赋值和static代码块合并成的

会先执行父类的clinit方法。

JVM会保证clinit方法的线程安全,比如写一个static的长执行方法,两个线程调用的时候会看到等待过程

初始化触发的时间点  new , 引用类的final字段,但是staticfinal的除外,  调用类的静态方法。  用reflect包反射调用,执行时main方法宿主类, 子类初始化先初始化父类


类加载器

不同的类加载器使用instanceof的时候会判断两个相同的Class生成的obj是返回false的。

双亲委派模型

每个类加载器的功能图上已经说得很清楚了。

说是双亲委派模型主要是说得1.2之后的所有的类加载器的实现的模式都是

实现的时候就是我们自己去实现findClass()方法,loadClass()方法里的逻辑是先调用了父类类加载器,当父类无法加载的时候调用findClass()方法。


破坏双亲委派模型

双亲的模型会有一个问题,默认了用户类会调用基础类,但是有些情况不是这样的,比如JNDI,JNDI是由启动加载器加载的,但是其确需要引用一些第三方的类,为了解决类似的情况,引入了ThreadContextClassLoader. JNDI, JDBC等都使用了这种情况


此外,为了热部署的OSGI技术也是一个没有使用这个结构的代表。



Tomcat类加载器架构

一个Web容器设计类加载的时候可能会遇到的问题:

1. 每个应用应该相互隔离, 因为可能用到了同一个类的不同版本

2. 各应用所使用的类库又应该可以共享,这样就不用每一个都拷贝一份servelt.jar jsp.jar等等

3. 服务器本身的类库应该与应用的类库相互隔离

4. 应该支持JSP生成类的热替换

所以tomcat的类加载器设计成这个样子的:



可以看出,出了JDK自己的加载器外,还有tomcat设计的类加载的目录

/common  可以被Tomcat和所有的Web应用共同使用的

/server   可以被Tomcat使用,不能被Web应用使用

/shared 被所有Web程序共同使用

/WebApp/WEB-INF/ 仅此Web应用可见

这样的类设计可以很好的实现上述的功能


OSGI灵活的类加载器

模块化技术的事实标准。

OSGI给每一个bundle使用了一个类加载器,当需要更换bundle的时候连同类加载器一起换掉。

比如BundleA对应了ClassLoaderA, 其通过Export到处了一个包,  这个包被BundleB所引用。

bundle自己的类加载器负责加载自己的类,以及调用启动类加载器加载rt.jar等公用内容。

而当bundleB需要加载Import A的包的时候就会委派给ClassLoaderA进行加载,因为不在同一个ClassLoader中同名类是可以共存的, 这样就保证了可以同时存在不同版本的jar包在开发环境中。

其类加载器的结构



对于OSGI还有很多需要学习的地方

相关文章
|
9月前
|
前端开发 安全 Java
聊聊Java虚拟机(一)—— 类加载子系统
虚拟机就是一款用来执行虚拟计算机指令的计算机软件。它相当于一台虚拟计算机。大体上,虚拟机分为系统虚拟机和程序虚拟机。系统虚拟机就相当于一台物理电脑,里面可以安装操作系统;程序虚拟机是为了执行单个计算机程序而设计出来的虚拟机。其中 Java 虚拟机就是**执行 Java 字节码指令的虚拟机**。
81 2
|
存储 前端开发 安全
JVM学习笔记(完结)
JVM学习笔记(完结)
|
4月前
|
缓存 前端开发 Java
JVM知识体系学习二:ClassLoader 类加载器、类加载器层次、类过载过程之双亲委派机制、类加载范围、自定义类加载器、编译器、懒加载模式、打破双亲委派机制
这篇文章详细介绍了JVM中ClassLoader的工作原理,包括类加载器的层次结构、双亲委派机制、类加载过程、自定义类加载器的实现,以及如何打破双亲委派机制来实现热部署等功能。
189 3
|
5月前
|
存储 算法 Java
深入解析 Java 虚拟机:内存区域、类加载与垃圾回收机制
本文介绍了 JVM 的内存区域划分、类加载过程及垃圾回收机制。内存区域包括程序计数器、堆、栈和元数据区,每个区域存储不同类型的数据。类加载过程涉及加载、验证、准备、解析和初始化五个步骤。垃圾回收机制主要在堆内存进行,通过可达性分析识别垃圾对象,并采用标记-清除、复制和标记-整理等算法进行回收。此外,还介绍了 CMS 和 G1 等垃圾回收器的特点。
159 0
深入解析 Java 虚拟机:内存区域、类加载与垃圾回收机制
|
6月前
|
存储 算法 Java
JVM组成结构详解:类加载、运行时数据区、执行引擎与垃圾收集器的协同工作
【8月更文挑战第25天】Java虚拟机(JVM)是Java平台的核心,它使Java程序能在任何支持JVM的平台上运行。JVM包含复杂的结构,如类加载子系统、运行时数据区、执行引擎、本地库接口和垃圾收集器。例如,当运行含有第三方库的程序时,类加载子系统会加载必要的.class文件;运行时数据区管理程序数据,如对象实例存储在堆中;执行引擎执行字节码;本地库接口允许Java调用本地应用程序;垃圾收集器则负责清理不再使用的对象,防止内存泄漏。这些组件协同工作,确保了Java程序的高效运行。
60 3
|
6月前
|
C# UED 开发者
WPF动画大揭秘:掌握动画技巧,让你的界面动起来,告别枯燥与乏味!
【8月更文挑战第31天】在WPF应用开发中,动画能显著提升用户体验,使其更加生动有趣。本文将介绍WPF动画的基础知识和实现方法,包括平移、缩放、旋转等常见类型,并通过示例代码展示如何使用`DoubleAnimation`创建平移动画。此外,还将介绍动画触发器的使用,帮助开发者更好地控制动画效果,提升应用的吸引力。
358 0
|
7月前
|
存储 前端开发 Java
(二)JVM成神路之剖析Java类加载子系统、双亲委派机制及线程上下文类加载器
上篇《初识Java虚拟机》文章中曾提及到:我们所编写的Java代码经过编译之后,会生成对应的class字节码文件,而在程序启动时会通过类加载子系统将这些字节码文件先装载进内存,然后再交由执行引擎执行。本文中则会对Java虚拟机的类加载机制以及执行引擎进行全面分析。
146 0
|
7月前
|
Java Perl
JVM内存问题之如何统计在JVM的类加载中,每一个类的实例数量,并按照数量降序排列
JVM内存问题之如何统计在JVM的类加载中,每一个类的实例数量,并按照数量降序排列
110 0
|
7月前
|
存储 安全 Java
开发与运维引用问题之JVM类加载过程如何解决
开发与运维引用问题之JVM类加载过程如何解决
49 0
|
7月前
|
存储 算法 Java
JAVA程序运行问题之Java类加载到JVM中加载类时,实际上加载的是什么如何解决
JAVA程序运行问题之Java类加载到JVM中加载类时,实际上加载的是什么如何解决