`
liuwenjie517333
  • 浏览: 25991 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

jvm之classLoader 初探

    博客分类:
  • jvm
 
阅读更多

jvmclassLoader

 

背景:

classLoader:类加载器。大家平时在开发工具编写的代码会保存为.java文件,然后使用工具(javac命令等).java文件编译为.class文件。classLoder是专门查找,加载和解析.class文件。

 

JVM中有三种classLoader,这三种ClassLoader都是有层级关系,并且三种ClassLoader加载.class和文件目录是有分工的

                 

 

                                    

 

JVM classLoader的分类

Ø  第一种:bootstrapClassLoader

            bootstrapClassLoader,据说是jdk底层用C++实现的引导类加载器,它主要负责加载%JAVA_HOME%/jre/lib-Xbootclasspath参数指定的路径以及%JAVA_HOME%/jre/classes中的类。比如rt.jar(包含了很多JSE中的api对应的class),在jvm运行时,如果通过class.getClassLoader方法返回null,则表示该类是被bootstrapClassLoader加载的

        

Ø  第二种:extendClassLoader

                  extendClassLoader java实现的一个classLoader(具体实现是做为sun.misc.Launcher内部实现类extendClassLoader),主要加载%JAVA_HOME%/jre/lib/ext,此路径下的所有classes目录以及java.ext.dirs系统变量指定的路径中类库。比如dnsns.jar中的class

                 

Ø  第三种:AppClassLoader

           AppClassLoader,用java实现的一个ClassLoader(具体实现是做为sun.misc.Launcher内部实现类AppClassLoader),主要加载应用中的class,也就是程序员写的.java编译成的.class

 

ClassLoader的特点

Ø  classLoader加载机制是双亲委托机制,比如AppClassLoader要加载A.class,首先判断自己有没有加载过,如果没有加载过,则会委托父加载器也就是extendClassLoader进行加载,如果父类加载器返回null,不加载,则在用自己加载器

Ø  2、同一个classLoader实例,对每个class只有加载一次,不会重复加载,比如AppClassLoader加载了A.class,如果再调用AppClassLoader.loadClass方法加载A.class,则会返回自己缓存中已经加载过的A.class

 

         打破classLoader的特性

         classLoader的特点并不是一层不变,不能打破的。为了实现某些功能,或者为了实现某个业务不得不牺牲既定的规则,business firesttechnology secondjvm也会打包既定的规则。

Ø  打破规则1双亲委托加载

                  大家知道java中定义了很多JNDI的接口,但是接口具体的实现却是由不同的厂家提供,这样就会出现个现象,因为JNDI的接口都是jdk提供的,也就是接口所在的class会被bootStrap加载,但是厂家的实现类,基本都放到了相应应用中,会被appClassLoader进行加载。JNDI接口在启动时,需要调用相应厂家的实现类,而这时会出现bootstrapClassLoader不能加载具体实现类(bootstrapClassLoader加载特点和路径决定了),为了解决这个问题,java设计团队提出了线程上下文类加载器(可以通过Thread.currentThread().getContextClassLoader()获得)。该加载器可以通过setContentClassLoader进行设置,如果没有设置过,则会使用父线程的classLoader,如果在应用程序都没有设置过,默认为appClassLoader

                  有了线程上下文classLoader,就比较好实现此功能了,在加载JNDI接口的代码里,通过线程上下文ClassLoader拿到AppClassLoader,加载JNDI具体的实现类,也就是bootStrapClassLoader,会调用appClassLoader进行实现类的加载。通过这样打破了双亲委托加载

        

Ø  打破规则2 同一个类只会被classLoader加载一次。同一个类可以被classLoader多次加载到jvm

         热代码替换:比如A.class修改后,可以直接加载到jvm内存中。主要实现思路为A.class的加载由自定义实现的ClassLoader进行类加载,主要是自定义的ClassLoader继承ClassLoader,自己读取A.class的信息,然后调用defineClass方法,让jvm计算出该class的内存信息

                 

                 

 

                  具体java代码:

                 

                 

import java.util.Map;

public interface IConfig {

	public String getConfig(Map<String, String> params);
}

 

    自定义classLoader

     

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class IConfigImplClassLoaderUtil {

	public IConfig getConfiObject(String classUrl){
		
		ClassLoader classLoader = new ClassLoader() {
			@Override
			protected Class<?> findClass(String className){
				System.out.println("==========findClass======");
				byte[] classBuffer = loadClassBuffer(className);
				return defineClass(null, classBuffer, 0, classBuffer.length);
			}
			
			private byte[] loadClassBuffer(String className) {
				return getClassBytesFromFile(className);
			};
			
			
			private byte[] getClassBytesFromFile(String className){
				ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
				FileInputStream fileInputStream = null;
				try {
					fileInputStream = new FileInputStream(className);
					byte[] buffer = new byte[1024];
					int length = -1;
					while((length = fileInputStream.read(buffer)) > -1){
						byteArrayOutputStream.write(buffer, 0, length);
					}
					
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}finally{
					if(null != fileInputStream){
						try {
							fileInputStream.close();
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}
				return byteArrayOutputStream.toByteArray();
			}
		}; 
		try {
			Class wifiClass = classLoader.loadClass(classUrl);
			return (IConfig) wifiClass.newInstance();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	public static void main(String[] args) {
		String classUrl = "D:\\TestConfig.class";
		IConfigImplClassLoaderUtil classLoaderUtil = new IConfigImplClassLoaderUtil();
		IConfig  wifiConfig = classLoaderUtil.getConfiObject(classUrl);
		Map<String, String> params = new HashMap<String, String>();
		params.put("param1", "jack_liu");
		params.put("valu1", "test1234567890");
		String result = wifiConfig.getConfig(params);
		System.out.println("result:" + result);
		//修改TestConfig.java,重新编译再把class放到D盘
		
		IConfig  wifiConfig1 = classLoaderUtil.getConfiObject(classUrl);
		result = wifiConfig1.getConfig(params);
		System.out.println("result:" + result);
		System.out.println(wifiConfig1 instanceof IConfig);
		System.out.println(wifiConfig1.getClass().getClassLoader());
		System.out.println(IConfig.class.getClassLoader());
		Thread.currentThread().getContextClassLoader();
	}
}

    

 注意:如果需要实现上面的例子,需要实现Iconfig接口

 

参考资料:http://my.oschina.net/aminqiao/blog/262601#OSC_h1_7

                  《深入理解java 虚拟机》

  • 大小: 14 KB
  • 大小: 30.7 KB
分享到:
评论

相关推荐

    JVM ClassLoader简析

    ClassLoader是JVM中的一个重要组件,它的主要任务是加载类的二进制数据,转换为Class对象,并供Java应用程序使用。本文将深入浅出地探讨JVM ClassLoader的工作原理和相关知识点。 首先,ClassLoader可以分为三种...

    JVM.zip_JVM代理_classloader

    而JVM代理(JVM Agent)和类加载器(ClassLoader)则是两个关键的概念,它们对于深入理解Java应用程序的运行机制至关重要。 **JVM代理** JVM代理是一种在JVM启动时或者运行时插入额外功能的方式,它允许开发者在不...

    探索JVM底层奥秘ClassLoader源码分析与案例讲解

    在JVM的运行机制中,ClassLoader起着至关重要的作用。ClassLoader负责查找并加载类到JVM中,使得程序得以运行。本篇将深入探讨ClassLoader的源码,通过实例解析其工作原理。 ClassLoader的基本工作流程可以概括为...

    java面试视频资源探索JVM底层奥秘ClassLoader源码分析与案例讲解

    java面试视频资源探索JVM底层奥秘ClassLoader源码分析与案例讲解提取方式是百度网盘分享地址

    ClassLoader运行机制 自己写的

    在Java虚拟机(JVM)中,类加载器(ClassLoader)是至关重要的组成部分,它负责查找和加载类的字节码文件。理解ClassLoader的工作机制对于深入掌握Java应用程序的运行至关重要。这里我们将详细讨论ClassLoader的运行...

    深入理解ClassLoader工作机制.docx

    Java虚拟机(JVM)中的ClassLoader是负责加载类到内存中的核心组件。它不仅承担着将字节码转换为可执行对象的重任,还参与了类生命周期的各个阶段,包括加载、验证、准备、解析、初始化、使用和卸载。这些阶段共同...

    JVM初探- 内存分配、GC原理与垃圾收集器

    JVM内存管理是Java虚拟机的核心机制之一,其主要包含对象的创建、内存分配、垃圾回收以及内存释放等过程。在JVM中,垃圾回收(GC)是自动管理内存的关键技术,其目的是回收不再使用的对象所占用的内存空间,以避免...

    初探JVM内存区域

    【初探JVM内存区域】 Java虚拟机(JVM)是Java编程语言的核心组成部分,它为Java应用程序提供了运行环境。理解JVM内存区域对于优化Java应用性能至关重要。本篇文章将详细探讨JVM中的主要内存区域及其作用。 1. **...

    classloader

    通过创建自定义ClassLoader,你可以定制JVM,使类文件的引入方式完全重新定义,这提供了很多实用和有趣的可能。这篇教程将对Java ClassLoader进行概述,并指导你构建一个示例ClassLoader,该ClassLoader可以自动编译...

    推荐一些JVM原理,JVM调优,JVM内存模型,JAVA并发 电子书1

    1. JVM原理:JVM的工作原理涉及类加载器(ClassLoader)、类文件(ClassFile)、内存管理及垃圾收集机制。类加载器负责将.class文件加载到内存中,为程序的运行准备数据结构。内存管理涉及JVM内存区域,包括堆、栈、...

    Tomcat研究之ClassLoader.pdf

    1. **Bootstrap ClassLoader**:这是JVM自带的类加载器,负责加载JVM自带的核心类库以及`$JAVA_HOME/jre/lib/ext/*.jar`目录下的扩展类库。 2. **System ClassLoader**:通常由JVM的`java.class.path`系统属性指向...

    JVM必知必会

    - **Bootstrap ClassLoader**:JVM级别的类加载器,负责加载`$JAVA_HOME/jre/lib`下的所有类库,不由Java实现,开发者无法直接操作。 - **Extension ClassLoader**:负责加载Java平台扩展功能的jar包,如`%JRE_HOME/...

    java ClassLoader机制及其在OSGi中的应用

    Java ClassLoader机制是Java虚拟机(JVM)中一个至关重要的组成部分,它的主要任务是将类的.class文件加载到JVM中,使得程序能够运行。ClassLoader不仅负责类的加载,还涉及类的验证、初始化等一系列过程。理解...

    Java ClassLoader定制实例

    在Java编程语言中,ClassLoader是一个至关重要的组成部分,它负责加载类到JVM(Java虚拟机)中。理解ClassLoader的工作原理以及如何定制它,对于深入学习Java的运行机制和进行高级应用开发具有重要意义。本篇文章将...

    ClassLoader小例子

    在Java编程语言中,ClassLoader是一个至关重要的组成部分,它负责加载类到JVM(Java虚拟机)中,使得程序能够执行。本示例"ClassLoader小例子"将深入探讨这个概念,并通过一个具体的程序来演示其工作原理。下面我们...

    java基础之JVM

    ### Java基础之JVM #### 一、JVM简介 **1.1 JVM是什么** Java Virtual Machine (JVM),即Java虚拟机,是Java技术的核心组成部分之一。它是一种抽象计算机,能够执行Java字节码(一种中间代码)的虚拟机环境。JVM...

    理解Java ClassLoader机制

    Java ClassLoader机制是Java运行时环境中的核心组件之一,它负责加载类到JVM(Java虚拟机)中,使得程序能够执行。理解ClassLoader的工作原理对于优化应用性能、处理类加载问题以及实现自定义加载器至关重要。 首先...

    狂神说JVM探究.rar

    【狂神说JVM探究】是一份集合了多种格式的学习资料,主要涵盖了Java虚拟机(JVM)的基础知识。这份资料出自B站上的【狂神说Java】系列教程,为快速入门JVM提供了详实的笔记。以下是根据这些资源可能包含的一些关键...

    ClassLoader 详解.doc

    Bootstrap ClassLoader并非继承自java.lang.ClassLoader,而是由JVM直接实现,因此在Java代码中无法直接获取和操作。它加载的类库路径可以通过-Xbootclasspath或-Dsun.boot.class.path系统属性进行设置。 2. ...

Global site tag (gtag.js) - Google Analytics