读《深入理解Java虚拟机》有感——第二部分:虚拟机类加载机制
1.关于“类加载器”和“生成的这个Class对象”: 1)类加载器 Bootstrap Loader(启动类加载器)、Extended Loader(标准扩展类加载器ExtClassLoader)、AppClass Loader(系统类加载器/应用程序类加载器AppClassLoader) 启动类加载器: 目的:加载java_home\lib目录下的字节码文件(如:rt.jar,含有java.lang.Object等基本类) 具体有哪些文件及加载顺序? 方式:加载System.getProperty("sun.boot.class.path")所指定的路径或jar,在使用Java运行程序时,也可以指定其搜索路径,例如:java -Djava.ext.dirs=d:\projects\testproj\classes HelloWorld 参考:http://www.cnblogs.com/ITtangtang/p/3978102.htm
标准扩展类加载器: 目的:加载java_home\lib\ext目录下的字节码文件
方式:加载System.getProperty("java.ext.dirs")所指定的路径或jar。在使用Java运行程序时,也可以指定其搜索路径,例如:java -Djava.ext.dirs=d:\projects\testproj\classes HelloWorld 结果:<实现类>sun.misc.Luncher@ExtClassLoader————————<继承关系>ClassLoader>URLClassLoader>AppClassLoader
应用程序类加载器: 方式:加载System.getProperty("java.class.path")所指定的路径或jar。在使用Java运行程序时,也可以加上-cp来覆盖原有的Classpath设置,例如: java -cp ./lavasoft/classesHelloWorld 结果:<实现类>sun.misc.Luncher@AppClassLoader————————<继承关系>ClassLoader>URLClassLoader>AppClassLoader
自定义类加载器: 方式:1)继承java.lang.ClassLoader并重写loadClass方法;2)继承java.lang.ClassLoader并重写findClass方法/**JDK1.2后推荐,原因见下方红色部分*/; 相关:
<一>java.lang.Object
1.getClass()
public final native Class<?> getClass(); //拿到运行时的Class对象【通过本地方法】
/**
*例子:class-Test>main>
* Class c =Person.getClass();
*/
/**
*实现:
*1)虚拟机启动
*2)虚拟机类加载——Test.class————加载阶段:方法区>外部接口>new java.lang.Class //Class<?>
*3)虚拟机类加载——java.lang.Object————【Test加载阶段】触发
*3)虚拟机类加载——Person.class ————【Test加载阶段】触发
*4)应用程序启动
*5)调用java.lang.ClassLoader>xxx1()、xxx2().....——返回运行时<Person>Class对象
*/
<二>java。lang.ClassLoader
1.loadClass(String name, boolean resolve) /**加载指定名称(包括包名)的二进制类型,同时指定是否解析*/
loadClass(String name)
protected Class<?> findClass(String name) throws ClassNotFoundException { //空方法
throw new ClassNotFoundException(name);
}
protected Class<?> loadClass(String name, boolean resolve) //拿到类加载器【通过本地方法】
throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
// First, check if the class has already been loaded
Class c = findLoadedClass(name);
if (c == null) {
long t0 = System.nanoTime();
try {
if (parent != null) {
c = parent.loadClass(name, false);
} else {
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
}
if (c == null) {
// If still not found, then invoke findClass in order
// to find the class.
long t1 = System.nanoTime();
c = findClass(name);
// this is the defining class loader; record the stats
sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
sun.misc.PerfCounter.getFindClasses().increment();
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
<三>java.lang.Class
1.getClassLoader()
/**例子:class-Test>main>
* Object o =new Object();
* System.out.println(o.getClass().getClassLoader());
结果>java.lang.NullPointerException
*/
/**
*Returns the class loader for the class.
*This method will return null in such implementations if this class was loaded by the bootstrap class loader.
*如果没有指定classLoader就默认返回bootstrap classLoader(启动类加载器),因为这个bootstrap classLoader
*用户拿不到实例,所以返回null表示返回的是bootstrap classLoader
*/
native ClassLoader getClassLoader0(); //拿到类加载器【通过本地方法】
public ClassLoader getClassLoader() {
ClassLoader cl = getClassLoader0();
if (cl == null)
return null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
ClassLoader.checkClassLoaderPermission(cl, Reflection.getCallerClass());
}
return cl;
} 2.指定类加载器加载类 Class.forName(name, initialize, loader)
2)与“生成的Class对象”关系 同一Class文件只有被同一类加载器加载,才能判断为相等————>相等的意义在于:1)不相等,会生成多个Class对象;相等,只会生成一个Class对象 2) 只有同一个Class对象,equals()、isAssignabaleFrom()、instanceof、isInstance()返回结果才相同;
3)双亲委派模型关系? 上一级持有下一级的一个引用,属于 has A关系 分工?(为什么叫双亲委派) 一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给上一层的类加载器去完成。只有当上级加载器在搜索范围找不到所需类,无法完成这个加载请求时,下级加载器才会尝试自己去加载 好处? Java类随着它的类加载器一起具备了一种优先级的层次关系
2.加载“类/接口”的策略: 非数组类/接口、数组类(组件类型为基本类型,如int[][]): 加载生成代表这个类的java.lang.Class对象后,将在类加载器的“类名称空间”上标识为“已加载”(因为前面已经讨论了,同一Class文件对应同一个类加载器才确定生成的是同一个Class对象)
连接阶段:
验证——文件格式、元数据、字节码
准备——在方法区为类变量分配内存并初始化
例子 编译时期 (类加载时)验证阶段—准备时期
static int i =20; 产生constantValue属性,但不会存入常量20 常规方式进行准备:初始化、分配内存
结果—————> 无 0
final static int i =20; 产生constantValue属性,并存20到constantValue 从对应constantValue取出来初始化
结果—————> 20 20
解析——将运行时常量池的符号引用替换为直接引用(指向内存目标的句柄),这一过程又叫“静态绑定/静态连接”
//例子(笔试常考题目)
public class Father {
private static int i =20;
static{
System.out.println("Father;(类构造器-before)"+i);
i =50;
System.out.println("Father;(类构造器-after)"+i);
}
public Father() {
System.out.println("Father:(实例构造器)"+ }
}
public class Son extends Father{
private static int i =20;
static{
System.out.println("Son;(类构造器-before)"+i);
i =50;
System.out.println("Son;(类构造器-after)"+i);
}
public Son() {
System.out.println("Son:(实例构造器)"+ }
}
public class Main {
public static void main(String[] args) {
new Son();
}
}
//输出结果:
/**
*Father;(类构造器-before)20
*Father;(类构造器-after)50
*Son;(类构造器-before)20
*Son;(类构造器-after)50
*Father:(实例构造器)50
*Son:(实例构造器)50
*/
读《深入理解Java虚拟机》有感——第二部分:虚拟机类加载机制的更多相关文章
- 深入理解Java内存模型中的虚拟机栈
深入理解Java内存模型中的虚拟机栈 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域,这些区域都会有各自的用途,以及创建和销毁的时间,有的区域会随着虚拟机进程的启 ...
- Java基础 -- 深入理解Java类型信息(Class对象)与反射机制
一 RTTI概念 认识Claa对象之前,先来了解一个概念,RTTI(Run-Time Type Identification)运行时类型识别,对于这个词一直是 C++ 中的概念,至于Java中出现RT ...
- (转)《深入理解java虚拟机》学习笔记6——类加载机制
Java虚拟机类加载过程是把Class类文件加载到内存,并对Class文件中的数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的java类型的过程. 在加载阶段,java虚拟机需要完成以下 ...
- Java程序员的必备知识-类加载机制详解
类加载器的概念 类加载器是一个用来加载类文件的类. Java源代码通过javac编译器编译成类文件.然后JVM来执行类文件中的字节码来执行程序.类加载器负责加载文件系统.网络或其他来源的类文件. JV ...
- JVM虚拟机内存溢出垃圾收集及类加载机制总结
1.Java内存区域与内存溢出异常 虚拟机栈:为虚拟机执行Java方法服务 本地方法栈:为虚拟机使用到的native方法服务. Java堆:是Java虚拟机所管理的内存中最大的一块,被所有线程共享的一 ...
- 深入理解Java虚拟机(第2版) 笔记目录
本篇为读深入理解Java虚拟机(第2版)一书的笔记目录. Java 运行期数据区 Java 垃圾回收算法 Java 内存分配策略 Java 类文件结构 Java 加载.链接.初始化 Java 类加载器
- 深入理解Java虚拟机(八)——类加载机制
是什么是类加载机制 Java虚拟机将class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这个过程就是类加载机制. 类的生命周期 一个类从加载到内存 ...
- 全面理解Java内存模型(JMM)及volatile关键字(转载)
关联文章: 深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型(@Annotation) 深入理解Java类加载器(ClassLoad ...
- 全面理解Java内存模型(JMM)及volatile关键字(转)
原文地址:全面理解Java内存模型(JMM)及volatile关键字 关联文章: 深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型( ...
随机推荐
- Java、Hibernate(JPA)注解大全
1.@Entity(name=”EntityName”) 必须,name为可选,对应数据库中一的个表 2.@Table(name=””,catalog=””,schema=””) 可选,通常和@Ent ...
- Java中的GOF23(23中设计模式)--------- 工厂模式(Factory)
Java中的GOF23(23中设计模式)--------- 工厂模式(Factory) 在给大家介绍工厂模式之前,我想和大家聊聊面向对象的那点事,在这里,引入三个概念. 开闭原则(Open Close ...
- 【GOF23设计模式】命令模式
来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_命令模式.数据库事务机制底层架构实现.撤销和回复 package com.test.command; public cla ...
- JS之跨域
今天学了跨域,迫不及待想跟大家分享!不妥之处希望大家指正. 首先来明确一下"跨域"这个概念. 跨域指的是,到外域去取数据.那什么是"外域"呢?我们先来了解同域. ...
- JS框架的一些小总结
闭包结构 为了防止和别的库的冲突,用闭包把整个框架安全地保护好. 我们待会的代码都写在里面.这里创建一个全局变量"window.O",就是在window对象里加个O,它等价于 &q ...
- 转 asp.net中如何退出整个框架(frameset),回到登录界面
如: <frameset rows= "74,*,0,0 " cols= "* " frameborder= "NO " border ...
- swift GCD使用指南
swift GCD使用指南 Grand Central Dispatch(GCD)是异步执行任务的技术之一.一般将应用程序中记述的线程管理用的代码在系统级中实现.开发者只需要定义想执行的任务并追加到适 ...
- java 之 对象与垃圾回收
1.垃圾回收机制只负责回收堆内存中的对象,不会回收任何物理资源(如数据库连接,网络IO等资源) 2.程序无法精确控制垃圾回收的运行,垃圾回收会在合适的时候运行.当对象永久的失去引用后,系统会在合适的时 ...
- 推些C语言与算法书籍
c语言系统学习与进阶: 1. C primer plus C primer plus 作为一本被人推崇备至的 c 入门经典,C primer plus 绝非浪得虚名.应该 算得上 C 教材里最好的入门 ...
- redis-集群(cluster)扫盲篇(一)
什么是redis的集群 按我个人的理解,redis集群就是实现多个redis节点之间进行数据的共享. 集群有什么好处: 将数据自动split到多个节点进行存储. 当集群中的一部分节点失效或者无法进行通 ...