- 浏览: 610206 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (334)
- java core (12)
- struts2.x (2)
- spring (3)
- hibernate (8)
- jpa (6)
- maven (2)
- osgi (5)
- eclipse (4)
- struts2.x+spring2.x+hibernate 整合 (5)
- ebs (0)
- html (0)
- vaadin (1)
- css (0)
- jquery (0)
- javascript (0)
- svn (1)
- cvs (0)
- axas2.x (0)
- eclipse+maven (9)
- annotation (0)
- 基于OSGi的动态化系统搭建 (1)
- notenet (1)
- jboss eclipse (4)
- eclipse工具 (4)
- jdk1.6+maven3.0.3+nuxeo+svn+felix+cxf+spring+springDM (6)
- spring dm (1)
- Nexus介绍 (1)
- proxool listener (0)
- oracle (4)
- mysql (8)
- 搭建你的全文检索 (1)
- hibernatehibernatehibernate (0)
- cvsearchcvsearch (0)
- mycvseach (0)
- asdfasdfasdf (0)
- propertiey (0)
- hibernate annotation (0)
- libs (0)
- icam (2)
- start 数据库配置 (0)
- jboss (1)
- 让Eclipse启动时显示选择workspace的对话框 (1)
- table表头固定 (1)
- s2s3h4 (0)
- leaver (0)
- mycvsaerchddd (0)
- 关于jboss5.0.1部署 (4)
- bookmarks (0)
- PersistenceUnitDeployment (0)
- mycom (0)
- HKEY_CURRENT_USER = &H80000001 (0)
- syspath (1)
- css div (1)
- Dreamweaver CS5 (0)
- generate (0)
- mysql查看表结构命令 (1)
- LOG IN ERROR EMAIL TO SB (0)
- struts2 handle static resource (1)
- jsf (2)
- log4j (1)
- jbpm4.4 (2)
- down: jbpm4.4 (1)
- jstl1.2 (1)
- spring annotation (1)
- java design pattern (1)
- cache (1)
- ehcache (1)
- 11111 (0)
- myge (0)
- pom.xml (0)
- springquartz (0)
- OpenStack (9)
- hadoop (2)
- nginx (1)
- hadoop openstack (1)
- os (1)
- hadoop-2.6.0 zookeeper-3.4.6 hbase-0.98.9-hadoop2 集群 (5)
- hadoop2.7.0 ha Spark (2)
- tess (0)
- system (1)
- asdf (0)
- hbase (2)
- hbase create table error (1)
- ekl (1)
- gitignore (1)
- gitlab-ci.yml (1)
- shell (1)
- elasticsearch (2)
- Azkaban 3.0+ (1)
- centos用命令 (1)
- hive (1)
- kafka (1)
- CaptureBasic (0)
- CentOS7 (1)
- dev tools (1)
- README.md (1)
- Error (1)
- teamviewerd.service (1)
- scala (1)
- spark (1)
- standard (1)
- gitlab (1)
- IDEA (0)
- ApplicationContext (1)
- 传统数仓 (1)
- redis install (1)
- MYSQL AND COLUME (1)
- java版本选择 (1)
- hue (1)
- npm (1)
- es (1)
- 版本管理 (1)
- 升级npm版本 (1)
- git (1)
- 服务器参数设置 (1)
- 调大 IDEA 编译内存大小 (0)
- CentOS8安装GitLab (1)
- gitlab安装使用 (1)
最新评论
-
ssydxa219:
vim /etc/security/limits.confvi ...
ekl -
Gamehu520:
table中无数据
hbase 出现的问题 -
Xleer0102:
为什么都是只有问没有答,哭晕在厕所
hbase 出现的问题 -
jiajiao_5413:
itext table -
CoderDream:
不完整,缺com.tcs.org.demostic.pub.u ...
struts2.3.1.1+hibernate3.6.9Final+spring3.1.0+proxool+maven+annotation
ClassLoader
类加载器(
class
loader)用来加载
Java 类到
Java 虚拟机中。
Java
源程序(
.java
文件)在经过
Java 编译器编译之后就被转换成
Java 字节代码(
.class
文件)。类加载器负责读取
Java 字节代码,并转换成
java.lang.Class 类的一个实例。
2. ClassLoader Hierarchy
JVM在加载类时,使用的是双亲委托模式
(delegation
model),也就是说除了
Bootstrap
ClassLoader之外,每个
ClassLoader都有一个
Parent
ClassLoader。
ClassLoader是按需进行加载
class文件。当
ClassLoader试图加载一个类时,首先检查本地缓冲,查看类是
否已被加载,如果类没有被加载,尝试委托给父
ClassLoader进行加载,如果父
ClassLoader加载失败,才会由该
ClassLoader进
行加载,从而避免了重复加载的问题。一下为类装载器层次图:
<!-- [if !supportLineBreakNewLine]-->
<!-- [endif]-->
<!-- [if !supportLists]-->a. <!-- [endif]-->Boostrap ClassLoader:启动类加载器,它用来加载一些 jdk的核心类,主要负责 核心 api 或 JAVA_HOME/jre/lib or JAVA_HOME/bin 下的类的加载,可以通过参数 -Xbootclasspath制定需要装入的 jar包。 它本身不是用 java实现的,所以肯定不是 ClassLoader的子类了。
<!-- [if !supportLists]-->b. <!-- [endif]-->Extendsion ClassLoader:扩展类加载器,用来加载一些扩展类,主要负责 JAVA_HOME/jre/lib/ext下类的加载 或 -Djava.ext.dirs 指定目录下的类 。此类是 ClassLoader的一个子类。
<!-- [if !supportLists]-->c.
<!-- [endif]-->System ClassLoader:系统类加载器
也叫
Application ClassLoader。是离我们最近的
ClassLoader了,它负责加载
CLASSPATH里指定的那些类。我们要实现自己的
ClassLoader也是继承自该类。
SystemClassLoader的父类是
Extension ClassLoader。
如果类
App1在本地缓冲中没有
class文件
(没有被加载
),那么它会自底向上依次查找是否已经加载了类,如果已经加载,则直接返回该类实例的引用。如
果
BootstrapClassLoader也未成功加载该类,那么会抛出异常,然后自顶向下依次尝试加载,如果到
App1
ClassLoader还没有加载成功,那么会抛出
ClassNotFoundException异常给调用者。
<!-- [if !supportLists]-->d.
<!-- [endif]-->User Custom ClassLoader/用户自定义类加载器
(java.lang.ClassLoader的子类
)
在程序运行期间
,
通过
java.lang.ClassLoader的子类动态加载
class文件
, 体现
java动态实时类装入特性
.
类加载器的特性:
1,
每个
ClassLoader都维护了一份自己的名称空间,
同一个名称空间里不能出现两个同名的类。
2,
为了实现
java安全沙箱模型顶层的类加载器安全机制
, java默认采用了
” 双亲委派的加载链
” 结构
如下图
:
Class Diagram:
类图中,
BootstrapClassLoader是一个单独的
java类,
其实在这里,
不应该叫他是一个
java类。
因为,
它已经完全不用
java实现了。
它是在 jvm启动时, 就被构造起来的, 负责 java平台核心库。(具体上面已经有介绍)
自定义类加载器加载一个类的步骤 :
ClassLoader 类加载逻辑分析, 以下逻辑是除 BootstrapClassLoader 外的类加载器加载流程 :
// 检查类是否已被装载过
Class c = findLoadedClass(name);
if (c == null ) { // 指定类未被装载过
try {
if (parent != null ) { // 如果父类加载器不为空, 则委派给父类加载
c = parent.loadClass(name, false );
} else {// 如果父类加载器为空, 则委派给启动类加载加载
c = findBootstrapClass0(name);
}
} catch (ClassNotFoundException e) {
// 启动类加载器或父类加载器抛出异常后, 当前类加载器将其
// 捕获, 并通过 findClass 方法, 由自身加载
c = findClass(name);
}
}
用
Class.forName
加载类
Class.forName使用的是被调用者的类加载器来加载类的
.
这种特性
, 证明了
java类加载器中的名称空间是唯一的
,
不会相互干扰
.
即在一般情况下 , 保证同一个类中所关联的其他类都是由当前类的类加载器所加载的 .
public static Class forName(String className)
throws ClassNotFoundException {
return forName0(className, true , ClassLoader.getCallerClassLoader());
}
/** Called after security checks have been made. */
private static native Class forName0(String name, boolean initialize,
ClassLoader loader)
throws ClassNotFoundException;
上图中 ClassLoader.getCallerClassLoader 就是得到调用当前 forName方法的类的类加载器
线程上下文类加载器
java默认的线程上下文类加载器是
系统类加载器
(AppClassLoader).
// Now create the class loader to use to launch the application
try {
loader = AppClassLoader.getAppClassLoader(extcl);
} catch (IOException e) {
throw new InternalError(
"Could not create application class loader" );
}
// Also set the context class loader for the primordial thread.
Thread.currentThread().setContextClassLoader(loader);
以上代码摘自 sun.misc.Launch的无参构造函数 Launch()。
使用线程上下文类加载器
, 可以在执行线程中
, 抛弃双亲委派加载链模式
, 使用线程上下文里的类加载器加载类
.
典型的例子有
, 通过线程上下文来加载第三方库
jndi实现
, 而不依赖于双亲委派
.
大部分
java app服务器
(jboss, tomcat..)也是采用
contextClassLoader来处理
web服务。
还有一些采用
hotswap 特性的框架
,
也使用了线程上下文类加载器
,
比如
seasar (full stack framework in japenese).
线程上下文从根本解决了一般应用不能违背双亲委派模式的问题 .
使 java类加载体系显得更灵活 .
随着多核时代的来临
, 相信多线程开发将会越来越多地进入程序员的实际编码过程中
. 因此
,
在编写基础设施时,
通过使用线程上下文来加载类
, 应该是一个很好的选择
.
当然
, 好东西都有利弊
. 使用线程上下文加载类
, 也要注意
, 保证多根需要通信的线程间的类加载器应该是同一个
,
防止因为不同的类加载器
,
导致类型转换异常
(ClassCastException).
自定义的类加载器实现
defineClass(String name, byte[] b, int off, int len,ProtectionDomain
protectionDomain)
是
java.lang.Classloader提供给开发人员
, 用来自定义加载
class的接口
.
使用该接口
,
可以动态的加载
class文件
. 例如
,
在
jdk中
,
URLClassLoader是配合
findClass方法来使用
defineClass,
可以从网络或硬盘上加载
class.
而使用类加载接口 , 并加上自己的实现逻辑 , 还可以定制出更多的高级特性 .
比如 ,一个简单的 hot swap 类加载器实现 :
import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
/**
* 可以重新载入同名类的类加载器实现 , 放弃了双亲委派的加载链模式 .
* 需要外部维护重载后的类的成员变量状态 .
*/
public class HotSwapClassLoader extends URLClassLoader {
public HotSwapClassLoader(URL[] urls) {
super (urls);
}
public HotSwapClassLoader(URL[] urls, ClassLoader parent) {
super (urls, parent);
}
public Class load(String name)
throws ClassNotFoundException {
return load(name, false );
}
public Class load(String name, boolean resolve)
throws ClassNotFoundException {
if ( null != super .findLoadedClass(name))
return reload(name, resolve);
Class clazz = super .findClass(name);
if (resolve)
super .resolveClass(clazz);
return clazz;
}
public Class reload(String name, boolean resolve)
throws ClassNotFoundException {
return new HotSwapClassLoader( super .getURLs(), super .getParent()).load(
name, resolve);
}
}
public class A {
private B b;
public void setB(B b) {
this .b = b;
}
public B getB() {
return b;
}
}
public class B {}
这个类的作用是可以重新载入同名的类,
但是,
为了实现
hotswap, 老的对象状态
需要通过其他方式拷贝到重载过的类生成的全新实例中来。
(A类中的
b实例
)
而新实例所依赖的 B类如果与老对象不是同一个类加载器加载的, 将会抛出类型转换异常 (ClassCastException).为了解决这种问题, HotSwapClassLoader自定义了 load方法 . 即当前类是由自身 classLoader加载的, 而内部依赖的类
还是老对象的 classLoader加载的 .
public class TestHotSwap {
public static void main(String args[]) {
A a = new A();
B b = new B();
a.setB(b);
System.out.printf("A classLoader is %s n" , a.getClass().getClassLoader());
System.out.printf("B classLoader is %s n" , b.getClass().getClassLoader());
System.out.printf("A.b classLoader is %s n" , a.getB().getClass().getClassLoader());
HotSwapClassLoader c1 = new HotSwapClassLoader( new URL[]{ new URL( "file:\e:\test\")} , a.getClass().getClassLoader());
Class clazz = c1.load(" test.hotswap.A ");
Object aInstance = clazz.newInstance();
Method method1 = clazz.getMethod(" setB ", B.class);
method1.invoke(aInstance, b);
Method method2 = clazz.getMethod(" getB ", null);
Object bInstance = method2.invoke(aInstance, null);
System.out.printf(" reloaded A.b classLoader is %s n", bInstance.getClass().getClassLoader());
}
}
public static void main(String[] args) {
ClassLoader cl = ClassLoader.getSystemClassLoader();
while(cl != null){
System.out.println(cl);
System.out.println("parent class loader: " + cl.getParent());
cl = cl.getParent();
}
}
sun.misc.Launcher$AppClassLoader@19821f
parent class loader: sun.misc.Launcher$ExtClassLoader@addbf1
sun.misc.Launcher$ExtClassLoader@addbf1
parent class loader: null
我们看到,当前系统类装载器为
AppClassLoader,AppClassLoader的父类装载器是
ExtClassLoader,
ExtClassLoader的父装载器为
null,表示为
BootstrapClassLoader。
BootstrapClassLoader由
JVM采用本地代码实现,因此没有对应的
Java类,所以
ExtClassLoader的
getParent()返回
null。
ClassLoader的职责之一是保护系统名字空间。以下为
ClassLoader类部分代码:
private ProtectionDomain preDefineClass(String name,
ProtectionDomain protectionDomain)
{
if (!checkName(name))
throw new NoClassDefFoundError("IllegalName: " + name);
if ((name != null) && name.startsWith("java.")) {
throw new SecurityException("Prohibited package name: " +
name.substring(0, name.lastIndexOf('.')));
}
if (protectionDomain == null) {
protectionDomain = getDefaultDomain();
}
if (name != null)
checkCerts(name, protectionDomain.getCodeSource());
return protectionDomain;
}
那么,当我们定义如下类 Foo,虽然能够通过编译,但是会报 java.lang.SecurityException: Prohibited package name: java.lang异常,因为我们试图将 Foo类写入到 java.lang包下。
package java.lang;
public class Foo {
public static void main(String args[]) throws Exception {
Foo f = new Foo();
System.out.println(f.toString());
}
}
<!-- [if !supportLists]-->3.
<!-- [endif]-->定制
ClassLoader
Java自带的
ClassLoader类的定义为:
public abstract class ClassLoader{
}
启动类加载器是 JVM通过调用 ClassLoader.loadClass()方法。
public Class<?> loadClass(String name) throws ClassNotFoundException {
return loadClass(name, false);
}
protected synchronized Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
// First, check if the class has already been loaded
Class c = findLoadedClass(name);
if (c == null) {
try {
if (parent != null) {
c = parent.loadClass(name, false);
} else {
c = findBootstrapClass0(name);
}
} catch (ClassNotFoundException e) {
// If still not found, then invoke findClass in order
// to find the class.
c = findClass(name);
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
protected Class<?> findClass(String name) throws ClassNotFoundException {
throw new ClassNotFoundException(name);
}
loadClass(String
name, boolean resolve)方法中的
resolve如果为
true,表示分析这个
Class对象,包括检查
Class
Loader是否已经初始化等。
loadClass(String
name) 在加载类之后不会对该类进行初始化,直到第一次使用该类时,才会对该类进行初始化。
那么,我们在定制
ClassLoader的时候,通常只需要覆写
findClass(String
name)方法。在
findClass(String
name)方法内,我们可以通过文件、网络
(URL)等形式获取字节码。以下为获取字节码的方法
:
public InputStream getResourceAsStream(String name);
public URL getResource(String name);
public InputStream getResourceAsStream(String name);
public Enumeration<URL> getResources(String name) throws IOException;
在取得字节码后,需要调用 defineClass()方法将字节数组转换成 Class对象,该方法签名如下:
protected final Class<?> defineClass(String name, byte[] b, int off, int len,
ProtectionDomain protectionDomain)
throws ClassFormatError
对于相同的类, JVM最多会载入一次。如果同一个 class文件被不同的 ClassLoader载入(定义),那么载入后的两个类是完全不同的 。
public class Foo{
//
private static final AtomicInteger COUNTER = new AtomicInteger(0);
public Foo() {
System.out.println("counter: " + COUNTER.incrementAndGet());
}
public static void main(String args[]) throws Exception {
URL urls[] = new URL[]{new URL("file:/c:/")};
URLClassLoader ucl1 = new URLClassLoader(urls);
URLClassLoader ucl2 = new URLClassLoader(urls);
Class<?> c1 = ucl1.loadClass("Foo");
Class<?> c2 = ucl2.loadClass("Foo");
System.out.println(c1 == c2);
c1.newInstance();
c2.newInstance();
}
}
以上程序需要保证
Foo.class
文件不在
classpath
路径下。从而使
AppClassLoader
无法加载
Foo.class
。
输出结果:
false
counter: 1
counter: 1
4. Web应用的
ClassLoader
绝大多数的
EJB容器,
Servlet容器等都会提供定制的
ClassLoader,来实现特定的功能。但是通常情况下,所有的
servlet和
filter使用一个
ClassLoader。每个
jsp都使用一个独立的
ClassLoader。
5. 隐式
(implicit)和显示
(explicit)的加载
隐式加载:我们使用
new关键字实例化一个类,就是隐身的加载了类。
显示加载分为两种:
java.lang.Class的
forName()方法;
java.lang.ClassLoader的
loadClass()方法。
Class.forName()方法有两个重载的版本:
public static Class<?> forName(String className)
throws ClassNotFoundException {
return forName0(className, true, ClassLoader.getCallerClassLoader());
}
public static Class<?> forName(String name, boolean initialize,
ClassLoader loader)
throws ClassNotFoundException
可以看出,
forName(String className)默认以
true和
ClassLoader.getCallerClassLoader()调用了三参数的重载方法。
ClassLoader.getCallerClassLoader()表示以
caller class loader加载类,并会初始化类
(即静态变量会被初始化,静态初始化块中的代码也会被执行
)。如果以
false和
ClassLoader.getCallerClassLoader()调用三参数的重载方法,表示加载后的类不会被初始化。
ClassLoader.loadClass()方法在类加载后,也同样不会初始化类。
6. 两个异常
(exception)
NoClassDefFoundError: 当
java源文件已编译成
.class文件
,但是
ClassLoader在运行期间搜寻路径
load某个类时
,没有找到
.class文件则抛出这个异常。
ClassNotFoundException: 试图通过一个
String变量来创建一个
Class类时不成功则抛出这个异常
package com.fnk.classloader;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import com.fnk.TestClass;
public class MultyClassLoader {
public static void main(String[] args) {
FileClassLoader classLoader1 = new FileClassLoader("./");
FileClassLoader classLoader2 = new FileClassLoader("./");
try {
/*
*在同一个类加载器中加载了类 com.fnk.classloader.TestClass和 com.fnk.TestClass虽然类名相同,但是不同的包下面所以可以加载。但如果加载同包同类名就会抛出重复加载的错误。
*/ Class c1 = classLoader1.loadClass("com.fnk.classloader.TestClass");
classLoader1.setDirectory("./src/");
Class c11 = classLoader1.findClass("com.fnk.TestClass");
/*TestClass是定义在 class path下面的类,虽然类名也是 com.fnk.TestClass。但是因为 TestClass是 App classloader加载的,而 c11是 classLoader1加载的。这样将 c11实例化的对象的引用赋值给 TestClass时就抛出 ClassCastException异常
*/
TestClass tc = (TestClass)c11.newInstance();
tc.test();
/*
* 不同的 classLoader中可以加载同包同类名的类。而且会被认为是不同的类。
* 如下面当我调用 tc1.equals(tc2)时返回了 false,如下我重载了 equals方法。
* public boolean equals(Object obj) {
* // TODO Auto-generated method stub
* if(obj instanceof TestClass)
* return true;
* else
* return super.equals(obj);
* }
* 我们可以让 TestClass类实现 Testf接口,那样就将 TestClass
对象赋值给 Testf接口,然后调用方法
*/
Class c2 = classLoader2.loadClass("com.fnk.classloader.TestClass");
Testf tc1 = (Testf)c1.newInstance();
Testf tc2 = (Testf)c2.newInstance();
tc1.test();tc2.test();
if(tc1.equals(tc2)){System.out.println("true");
}else{System.out.println("false");
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
java class的加载采用所谓的委托模式(
Delegation Modle),当调用一个
ClassLoader.loadClass()加载一个类的时候,将遵循以下的步骤:
1)检查这个类是否已经被加载进来了?
2)如果还没有加载,调用父对象加载该类
3)如果父对象无法加载,调用本对象的
findClass()取得这个类。
所以当创建自己的
Class Loader时,只需要重载
findClass()这个方法。
Unloading? Reloading?
当
一个
java class被加载到
JVM之后,它有没有可能被卸载呢?我们知道
Win32有
FreeLibrary()函数,
Posix有
dlclose()函数可以被调用来卸载指定的动态连接库,但是
Java并没有提供一个
UnloadClass()的方法来卸载指定的类。
在
Java中,
java class的卸载仅仅是一种对系统的优化,有助于减少应用对内存的占用。既然是一种优化方法,那么就完全是
JVM自行决定如何实现,对
Java开发人员来说是完全透明的。
在
什么时候一个
java class/interface会被卸载呢?
Sun公司的原话是这么说
的:
"class or interface may be unloaded if and only if its class loader is unreachable. Classes loaded by the bootstrap loader may not be unloaded."
事实上我们关心的不是如何卸载类的,我们关心的是如何更新已经被加载了的类从而更新应用的功能。
JSP则是一个非常典型的例子,如果一个
JSP文件被更改了,应用服务器则需要把更改后的
JSP重新编译,然后加载新生成的类来响应后继的请求。
其
实一个已经加载的类是无法被更新的,如果你试图用同一个
ClassLoader再次加载同一个类,就会得到异常
(
java.lang.LinkageError: duplicate class definition),我们只能够重新创建一个新的
ClassLoader实例来再次加载新类。至于原来已经加载的类,开发人员不必去管它,因为它可能还有实例正在被使用,只要相关的实例都被内存回收了,
那么
JVM就会在适当的时候把不会再使用的类卸载
。
发表评论
-
idea code
2019-10-14 15:35 284MNQ043JMTU-eyJsaWNlbnNlSWQiOiJN ... -
idea
2018-04-01 07:29 0http://idea.iteblog.com/ ... -
hashmap和hashtable
2012-12-20 15:04 944Java中hashmap和hashtable的区别 ... -
jdk schedule timer task
2012-12-19 10:33 818Implementing and scheduling a t ... -
synchronized
2012-11-01 14:29 01.把 synchronized (i) { 放在 while ... -
sdfasdfasdf
2012-10-19 18:12 0Hi, this is jar, it is really ... -
syspath
2012-09-21 13:42 1170Locale locale = Locale.getDefau ... -
gc---java
2012-06-28 10:38 0JVM内存模型中分两大块 ... -
JAVA_OPTS
2012-06-16 21:40 0set JAVA_OPTS=%JAVA_OPTS% -Xms5 ... -
daemon thread
2012-03-09 22:04 1138用户线程:是你自己写的,可以手工调用;守护线程(Daemon ... -
集合的区别总结
2012-03-07 10:32 1271hashMap和hashTable的几点区别 1. ... -
synchronized 规则
2012-02-27 11:05 0synchronized 方法控制对类 ... -
JDK1.6中文版的对HashMap
2012-02-27 10:28 1294以下是 JDK1.6 中 ... -
JDK1.6中文版的对HashMap
2012-02-27 10:27 932以下是 JDK1.6 中文版的对 HashMap 的具体介绍 ... -
HashMap
2012-02-27 10:04 972Map map = new HashMap(); ... -
Collection
2012-02-27 09:59 854线性表,链表,哈希表是常用的数据结构,在进行Java开发时,J ... -
until
2012-02-27 08:04 0Until 1 1. Be at the star ... -
Java Thread
2011-12-30 10:11 101481、线程概述 几乎所有的操作系统都支持同时运行 ...
相关推荐
ClassLoader运行机制 自己写的ClassLoader运行机制 自己写的ClassLoader运行机制 自己写的ClassLoader运行机制 自己写的ClassLoader运行机制 自己写的
破解java加密的ClassLoader.java,在classloader植入破解代码
自定义classloader的使用
Java ClassLoader定制实例
java classloader classpath 张孝祥
理解Java ClassLoader机制
用于验证理解Android中Classloader加载类机制的程序demo,从中可以对比DexClassLoader和PathClassLoader的区别联系。
ClassLoader类加载机制和原理详解
内容简介: ClassLoader体系结构 类装载器在JVM中并不是唯一的,JVM自带了三个装载器,用户也可以根据自己的需求自定义新的装载器,这些装载器的体系结构可以看作是树状结构,如图1所示:
关于J2EE服务器的ClassLoader的原理,该文档清晰了揭示了jvm装载类的顺序,同时用户可以自定义修改classLoader的配置 通过该文档,可以加深对Java虚拟机的理解
重温java之classloader体系结构(含hotswap) 启动类加载器 扩展类加载器 系统类加载器
【图解版】深入分析ClassLoader类加载工作机制,从原理到JVM的装载过程,详情分析了ClassLoader加载类以及自定义类加载器的过程,不可用于商业用途,如有版权问题,请联系删除!
深入了解Java_ClassLoader,Bytecde.pdf
一个开源的Cplusplus类加载器,基于它实现了一个简单的例子,见我写的classloader的文章。
classloader 加密解密应用程序 ,反编译class
JVM内存模型,类加载模式工作机制详细,内存屏障,类从被加载到虚拟机内存中开始,直到卸载出内存为止,它的整个生命周期包括了:加载、验证、准备、解析、初始化、使用和卸载这7个阶段。其中,验证、准备和解析这三...
Classloader
ClassLoader类加载器讲解,理解JAVA类加载机制