1.Class文件内容格式

2.一个class文件是被加载到内存的过程是怎样的?

  1. loading

把一个class文件装到内存里,class文件是一个二进制,一个个的字节

  1. linking
  • Verification:校验装载进来的class文件是不是符合jvm规定,如果不符合规范,直接就被拒掉了
  • Preparation:把class文件静态变量赋默认值,比如int i = 8;那么此时i = 0而不是8
  • Resolution:把class文件中的类、方法、属性等符号引用转换为直接引用,常量池里面用到的符号引用,解析为指针、偏移量等内存直接引用地址
  1. Initlalizing

    给变量赋初始值int i = 8,上个步骤是0,到这一步才真正的赋值为8

一个class文件被加载到内存之后是创建了两块内容

1.分配一块内存用来存储class文件的内容

2.创建一个class对象,指向class文件内容的内存地址

3.类加载器



loading:双亲委派

定义:如果一个类加载器收到了加载某个类的请求,则该类加载器并不会直接去加载该类,而是把这个请求委派给父类加载器,如果父类加载器已经把这个类加载进内存,则直接返回,如果没有则继续委派给父加载器,以此类推,只有当父类加载器在其搜索范围内无法找到所需的类,并将该结果反馈给子类加载器,子类加载器会尝试去自己加载。

为什么需要双亲委派?

主要是为了安全。如果有人想替换系统级别的类:String.java。篡改它的实现,但是在这种机制下这些系统的类已经被Bootstrap classLoader加载过了,所以并不会再去加载,从一定程度上防止了危险代码的植入

父加载器

父加载器不是“类加载器的加载器”,也不是“类加载器的父类加载器”

在Launcher类(ClassLoader的一个包装启动类)中,可以看到类加载器范围

bootstartap

ext

app

4.自定义类加载器

  • 定义一个类继承ClassLoader
  • 重写模板方法:findClass,并在内部调用defineClass

load class---->findClass(模板方法/钩子函数)

public class OverrideFindClass extends ClassLoader {
/**
* 框架,类库,tomcat/spring都有自定义的类加载器
* 自定义类加载器
* 下面是思路:
* 1.把class文件以流的方式读入内存
* 2.调用classLoader的内置方法:defineClass
*
*/
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
File file = new File("", name.replaceAll(".", "/").concat(".class"));
try {
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int b = 0;
while ((b = fis.read()) != 0) {
baos.write(b);
}
byte[] bytes = baos.toByteArray();
baos.close();
//把二进制字节流转化为类
return defineClass(name, bytes, 0, bytes.length);
} catch (Exception e) {
e.printStackTrace();
}
return super.findClass(name);
}
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
ClassLoader classLoader = new OverrideFindClass();
//name是指项目内,文件的包路径
Class clazz = classLoader.loadClass("classloader.Hello");
Hello hello = (Hello) clazz.newInstance();
hello.m();
System.out.println(classLoader.getClass().getClassLoader());
System.out.println(classLoader.getParent());
}
}

Java可以解释执行也可以即时编译

-Xmixed:默认混合模式,解释执行+热点代码编译

  • 什么是热点代码编译

多次被调用的方法,多次被调用的循环,内部维护了一个计数器,如果发现某个方法被执行了很多次,就会被编译为本地代码,再用的话就可以直接执行

  • 既然即时编译运行速度这么快,为什么不直接都编译为本地代码呢

第一:Java现在的解释器的效率已经非常高了,在一些代码的执行上也不输给编译器

第二:如果类库的类很多,二话不说直接编译,那速度必然是很慢很慢,所以就采用了混合模式

-Xint:解释模式,启动很快,执行稍慢

-Xcomp:纯编译模式,启动很慢,执行很快

自定义classLoader的父亲

  • 继承ClassLoader
  • 指定父加载器:super(parent)
public class SetClassLoaderParentBySelf  {
static OverrideFindClass parent = new OverrideFindClass();
static class MyLoader extends ClassLoader {
public MyLoader(){
super(parent);
//不指定的话默认是AppClassLoader
//System.out.println(this.getParent());
}
}
public static void main(String[] args) {
MyLoader loader = new MyLoader();
}
}

5.打破双亲委派

如何打破?

  • 重写loadClass

何时打破?

  • jdk1.2之前,自定义classLoader都必须重写loadClass()
  • 热启动,热部署:tomcat有自定义的classLoader(可以加在同一类库的不同版本,指不同应用,即每个应用都有自己的classLoader,所以出现同名不同版本的类库依然是可以都加载进来的)

如何自定义classLoader实现热部署的效果?

重写loadClass,干掉上一次加载的classLoader

public class DapoShuangQinWeiPai {
private static class MyLoader extends ClassLoader {
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
File file = new File("H:/Learning/jvm/src/main/java/" + name.replace(".", "/").concat(".class"));
if (!file.exists()) {
return super.loadClass(name);
}
try {
InputStream is = new FileInputStream(file);
byte[] b = new byte[is.available()];
is.read();
return defineClass(name, b, 0, b.length);
} catch (IOException e) {
e.printStackTrace();
}
return super.loadClass(name);
}
}
public static void main(String[] args) {
MyLoader loader = new MyLoader();
try {
Class clazz = loader.loadClass("classloader.Hello");
loader = new MyLoader();
Class cla = loader.loadClass("classloader.Hello");
System.out.println(cla == clazz);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}

6.new对象的步骤

  1. 给对象申请内存
  2. 给对象的成员变量赋默认值
  3. 调用构造方法,给成员变量赋初始值

详解Class加载过程的更多相关文章

  1. 详解ListView加载网络图片的优化,让你轻松掌握!

    详解ListView加载网络图片的优化,让你轻松掌握! 写博客辛苦了,转载的朋友请标明出处哦,finddreams(http://blog.csdn.net/finddreams/article/de ...

  2. linux modprobe命令参数及用法详解--linux加载模块命令

    转:http://www.linuxso.com/command/modprobe.html modprobe(module probe) 功能说明:自动处理可载入模块. 语 法:modprobe [ ...

  3. Google推荐——Glide使用详解(图片加载框架)

    零.前言 本文所使用的Glide版本为3.7.0 一.简介 Glide,一个被google所推荐的图片加载库,作者是bumptech.这个库被广泛运用在google的开源项目中,包括2014年的goo ...

  4. 详解ListView加载网络图片的优化

    我们来了解一些ListView在加载大量网络图片的时候存在的常见问题: 1.性能问题,ListView的滑动有卡顿,不流畅,造成非常糟糕的用户体验. 2.图片的错位问题. 3.图片太大,加载Bitma ...

  5. web.xml的加载过程配置详解

      一:web.xml加载过程 简单说一下,web.xml的加载过程.当我们启动一个WEB项目容器时,容器包括(JBoss,Tomcat等).首先会去读取web.xml配置文件里的配置,当这一步骤没有 ...

  6. <JVM中篇:字节码与类的加载篇>03-类的加载过程(类的生命周期)详解

    笔记来源:尚硅谷JVM全套教程,百万播放,全网巅峰(宋红康详解java虚拟机) 同步更新:https://gitee.com/vectorx/NOTE_JVM https://codechina.cs ...

  7. ELF文件的加载过程(load_elf_binary函数详解)--Linux进程的管理与调度(十三)

    加载和动态链接 从编译/链接和运行的角度看,应用程序和库程序的连接有两种方式. 一种是固定的.静态的连接,就是把需要用到的库函数的目标代码(二进制)代码从程序库中抽取出来,链接进应用软件的目标映像中: ...

  8. linux内核剖析(零)linux系统启动过程详解-开机加电后发生了什么

    本文参考了如下文章 深入理解linux启动过程 mbr (主引导记录(Master Boot Record)) 电脑从开机加电到操作系统main函数之前执行的过程 详解linux系统的启动过程及系统初 ...

  9. JVM——类的加载过程

    附一张图方便理解,一个类的执行过程 类的加载过程,简明的来说 类装饰器就是寻找类的字节码文件并构造出类在JVM内部表示的对象组件.在Java中,类装载器把一个类装入JVM中,要经过以下步骤: 装载:查 ...

随机推荐

  1. [第二届全国中学生网络安全竞赛]bypass

    前几天拿到了线下赛的源码,做做看.这道主要是命令执行的黑名单绕过 先看看给出的代码: <?php highlight_file(__FILE__); error_reporting(0); $b ...

  2. C016:字符串倒置

    代码: #include "stdafx.h" #include <string.h> int _tmain(int argc, _TCHAR* argv[]) { c ...

  3. Q20200511-01 翻转字符串

    需求:做一函数将字符串倒转过来 程序: package test4; public class Reverse { public static String reverse(String origin ...

  4. jdk1.8 时间工具类,可以满足基本操作

    时间工具类 public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd"; public static final S ...

  5. selenium做UI自动化时,模拟鼠标各种操作的ActionChains的用法

    1.selenium做自动化的时候,需要模拟鼠标进行单击.双击.右键.拖拽等操作,selenium提供了ActionChains类来进行处理. 2.执行原理:当你调用ActionChains的方法时, ...

  6. C#开发PACS医学影像处理系统(十一):Dicom影像挂片协议

    通俗点说,挂片协议可以看作整个系统的一个相对复杂一点的配置文件,可以用JSON或XML格式来读取与保存, 另外,可以制作一个独立的exe配置程序来管理这些挂片协议. 假设配置了CT的挂片协议的右键菜单 ...

  7. css3 压缩及验证工具

    1.css w3c统一验证工具 网址:http://www.csstats.com/ 如果你想要更全面的,这个神奇,你值得拥有: w3c统一验证工具:http://validator.w3.org/u ...

  8. 学习 | jQuery移动端页面组件化开发(一)

    最近在学习移动端组件化开发web页面,其中有好多小细节,值的去思考. 主要介绍JS的思路,具体的代码就不贴了,主要是想表达出一种思路 总体来说 1.入口文件,在入口文件中导入插件,插件样式,jquer ...

  9. Docker部署ElasticSearch以及使用

    ElasticSearch笔记 1. ElasticSearch前期 1.1 聊聊ElasticSearch的简介 ​ Elaticsearch,简称为es, es是一个开源的高扩展的分布式全文检索引 ...

  10. Linux实战(7):centos7安装xrdp

    系统环境:最小化安装,无安装桌面化 操作 yum更新 yum -y update 安装依赖. tigervnc-server.xrdp .GNOME Desktop yum -y install ep ...