`

类加载,反射,双亲委派,生命周期

    博客分类:
  • jvm
阅读更多
21.深入理解java反射(运行时校验读取class文件信息的字段,方法,构造方法等)
https://www.cnblogs.com/luoxn28/p/5686794.html
RTTI在编译知道此类型去验证,运行时让我们知道是什么类型,
反射打破这个规律在运行时,去验证加载,匿名对象的类信息就在运行时被完全确定下来,而在编译时不需要知道任何事情。
reflect类库一起对反射的概念进行了支持,该类库包含了Field字段、Method方法以及Constructor构造器类(每个类都实现了Member接口)。JVM在运行时创建这些类型的对象。
对RTTI(传统的加载class对象)来说,编译器在编译时打开和检查.class文件(也就是可以用普通方法调用对象的所有方法);而对于反射机制来说,.class文件在编译时是获取不到的,所以是在运行时打开和检查.class文件

22.深入理解类加载机制和生命周期
类加载机制:把数据从class文件加载到内存,并对这内存数据进行-校验,转换解析,初始化,最终形成可以被jvm直接使用的类型对象。
运行期间完成:类型加载,连接,初始化。
class文件:一串二进制字节流。

类加载生命周期包括(把class文件加载初始化到jvm内存里):

加载:1获取要加载的类二进制字节流(class文件),2这个字节流按照jvm所需要的格式(数据结构)放到方法区中,3在内存中实例化class类的对象放在方法区里,这个对象作为方法区访问具体数据结构访问入口。

连接-验证:class文件可能不仅java再用,所有对于此文件的必须验证,
对文件格式(内容中的开头标识,常量池中常量类型,常量索引指向,符合utf8等,以上是验证字节流,通过验证,之后验证方法区的存储结构),
元数据(是否有父类,是否被继承final修饰,是否实现父类接口实现方法,类的字段是否与父类产生矛盾),
字节码(对垒方法体校验,类型转换,类型不被方法外使用),
符号引用验证(引用中是否找到引用的类,private是否被当前类访问)

连接-准备:为类变量分配内存(不包括实例变量),并设置初始值。stati修饰的变量将在方法区中进行分配,比如 public status int value =123;

连接-解析:类或接口的解析,字段解析,类方法解析,接口方法解析,jvm在常量池的引用替换为直接引用的过程。

初始化:类先初始化父类,<clinit>方法(static方法块生成的<clinit>方法),构造器初始化,
如果是接口不会先执行父类的<clinit>方法,只有父类定义时才会初始化。
jvm保证<clinit>多线程访问方法加锁同步,其中一个线程执行完,其他线程也不会唤醒,因为一个类型只会初始化一次。
使用:
卸载:

23.深入理解类加载器
类加载器:把class文件解析成服务用到的二进制流,通过一个类全限定名来获取此类二进制字节流过程的实现。
obj.getClass() instanceof org.classloading.obj
如果我们自定义加载器加载与当前系统应用程序类加载器加载的做equels,返回false,虽然加载了同一个class文件,但是两个独立的类。

从更大的角度看,jvm虚拟机类加载器,2类,分为1.启动类加载器,2.所有其他类加载器,独立于hotSpot虚拟机排布,都集成java.lang.ClassLoader

从java的jdk角度看,jvm虚拟机类加载器,3类,分为1.启动类加载器,\lib目录类库加载到虚拟机内存中,2.扩展类加载器,\lib\ext目录类库加载到虚拟机内存中,3.应用程序类加载器,用户类路径加载到虚拟机内存中。

24.双亲委派模型
双亲委派模型:类加载器之间的层次关系(启动类加载器->扩展类加载器->应用程序类加载器->自定义加载器)。
工作原理:类加载器收到加载请求,会把请求委派给父类加载器去完成,当父类反馈没有找到所需要的类,子类才去加载。
如果自己重写了Object类,结果是虽然正常编译,但无法被加载运行。
java.lang.ClassLoader的loadClass方法是双亲委派模式的实现。
看loadClass源码也是双亲委派的原理:
先检查是否被加载过,如果已加载返回加载的类,如果没有去父类加载,如果没有找到没有完成加载,再去子类调用本身额的类加载。

1.保证了java程序稳定,不让子类随意修改。
2.如果不适用双亲委派,每次不会到父类加载,每个子类都会自行加载,导致重复多个加载。

双亲委派模型在jdk1.2之后才使用,loadClass在1.0就有了,为了实现向前兼容。有了findClass()保证父类加载失败,再加载自己。

线程上下文加载器:有一种场景父加载器会调回用户代码,不可能给用户代码生成认识这些代码,线程上下文加载器开启long.Thread类的setContextClassLoaser方法做一些自己的事情。

类加载器与OSGi
https://www.cnblogs.com/doit8791/p/5820037.html
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics