java中类加载的全过程及内存图分析
类加载机制:
jvm把class文件加载到内存,并对数据进行校验、解析和初始化,最终形成jvm可以直接使用的java类型的过程。
(1)加载
将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区中的运行时数据结构,在堆中生成一个代表这个类的java.lang.Class对象,作为方法区类数据的访问入口。
(2)链接 将java类的二进制代码合并到jvm的运行状态之中的过程
2.1 验证
确保加载的类信息符合jvm规范,没有安全方面的问题。
2.2 准备
正式为类变量(static变量)分配内存并设置类变量初始值的阶段,这些内存都将在方法区中进行分配。
2.3 解析
虚拟机常量池内的符号引用替换为直接引用的过程。(比如String s ="aaa",转化为 s的地址指向“aaa”的地址)
(3)初始化
初始化阶段是执行类构造器方法的过程。类构造器方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块(static块)中的语句合并产生的。
当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先初始化其父类的初始化
虚拟机会保证一个类的构造器方法在多线程环境中被正确加锁和同步
当访问一个java类的静态域时,只有真正声明这个静态变量的类才会被初始化。
类加载过程分为:类的主动引用和类的被动引用
类的主动引用(一定会发生类的初始化)
--new一个类的对象
--调用类的静态成员(除了final常量)和静态方法
--使用java.lang.reflect包的方法对类进行反射调用
--当初始化一个类,如果其父类没有被初始化,则先初始化他的父类
--当要执行某个程序时,一定先启动main方法所在的类
类的被动引用(不会发生类的初始化)
--当访问一个静态变量时,只有真正生命这个静态变量的类才会被初始化(通过子类引用父类的静态变量,不会导致子类初始化)
--通过数组定义类应用,不会触发此类的初始化 A[] a = new A[10];
--引用常量(final类型)不会触发此类的初始化(常量在编译阶段就存入调用类的常量池中了)
类加载器的层次结构(树状结构)
引导类加载器(bootstrap class loader)
--他用类加载java 的核心库(String 、Integer、List。。。)在jre/lib/rt.jar路径下的内容,是用C代码来实现的,并不继承自java.lang.ClassLoader。
--加载扩展类和应用程序类加载器。并指定他们的父类加载器。
扩展类加载器(extensions class loader)
--用来加载java的扩展库(jre/ext/*.jar路径下的内容)java虚拟机的实现会自动提供一个扩展目录。该类加载器在此目录里面查找并加载java类。
应用程序类加载器(application class loader)
--他根据java应用的类路径(classpath路径),一般来说,java应用的类都是由他来完成加载的
自定义类加载器
--开发人员可以通过继承java.lang.ClassLoader类的方式实现自己的类加载器,以满足一些特殊的需求。
扩展类加载器、应用程序类加载器、自定义类加载器均是由java实现,都继承java.lang.ClassLoader类。
类加载器的代理模式:双亲委托机制
--就是某个特定的类加载器在接收到加载类的请求后,首先将加载任务委托给父类加载器,一次追溯,直到最高的爷爷辈的,如果父类加载器可以完成类加载任务,就成功返回;只要父类加载器无法完成次加载任务时,才自己加载。
--双亲机制是为了保证java核心库的类型安全,不会出现用户自己能定义java.lang.Object类的情况。
双亲委托机制是代理模式的一种,并不是所有的类加载器都采用双亲委托机制,tomcat服务器类加载器也使用代理模式,所不同的是他是首先尝试自己去加载某个类,如果找不到在代理给父类加载器。
java中类加载的全过程及内存图分析的更多相关文章
- 【java虚拟机序列】java中的垃圾回收与内存分配策略
在[java虚拟机系列]java虚拟机系列之JVM总述中我们已经详细讲解过java中的内存模型,了解了关于JVM中内存管理的基本知识,接下来本博客将带领大家了解java中的垃圾回收与内存分配策略. 垃 ...
- java 中类加载器
jar 运行过程和类加载机制有关,而类加载机制又和我们自定义的类加载器有关,现在我们先来了解一下双亲委派模式. java 中类加载器分为三个: BootstrapClassLoader 负责加载 ${ ...
- ClassLoader Java中类加载出现在哪个阶段,编译期和运行期? 类加载和类装载是一样的吗
1.ClassLoader Java中类加载出现在哪个阶段,编译期和运行期? 类加载和类装载是一样的吗? :当然是运行期间啊,我自己有个理解误区,改正后如下:编译期间编译器是不去加载类的,只负责编译而 ...
- java中的各种数据类型在内存中存储的方式
原文地址:http://blog.csdn.net/aaa1117a8w5s6d/article/details/8251456 1.Java是如何管理内存的 java的内存管理就是对象的分配和释放问 ...
- Java中的垃圾回收机制&内存管理&内存泄漏
1. Java在创建对象时,会自动分配内存,并当该对象引用不存在的时候,释放这块内存. 为什么呢? 因为Java中使用被称为垃圾收集器的技术来监视Java程序的运行,当对象不再使用时,就自动释放对象所 ...
- 面试官:小伙子,你给我说一下Java中什么情况会导致内存泄漏呢?
概念 内存泄露:指程序中动态分配内存给一些临时对象,但对象不会被GC回收,它始终占用内存,被分配的对象可达但已无用.即无用对象持续占有内存或无用对象的内存得不到及时释放,从而造成的内存空间浪费. 可达 ...
- Java中堆、栈、常量池分析
栈用于存储局部变量,包括基本类型的变量(方法语句块内部定义的变量.方法中的形参).引用类型的变量,它们都是存储在各自的方法栈中,随着方法的执行完成而消失: 堆用于存储引用类型变量所指向的对象,包括普通 ...
- Java中的NIO和IO的对比分析
总的来说,java中的IO和NIO主要有三点区别: IO NIO 面向流 面向缓冲 阻塞IO 非阻塞IO 无 选择器(Selectors) 1.面向流与面向缓冲 Java NIO和IO之间第一个最大的 ...
- JAVA中IO和NIO的详解分析,内容来自网络和自己总结
用一个例子来阐释: 一辆客车上有10个乘客,他们的目的地各不相同,当没有售票员的时候,司机就需要不断的询问每一站是否有乘客需要下车,需要则停下,不需要则继续开车,这种就是阻塞的方式. 当有售票员的时候 ...
随机推荐
- 12、Spring Boot 2.x 集成 MongoDB
1.12 Spring Boot 2.x 集成 MongoDB 完整源码: Spring-Boot-Demos
- Ubuntu 执行 apt-get install ××× 报错
执行apt-get install fcitx时,报如下错误 grub-pc E: Sub-process /usr/bin/dpkg returned an error code (1) 通过执行下 ...
- 037_自动添加防火墙规则,开启某些服务或端口(适用于 RHEL7)
#!/bin/bash#设置变量定义需要添加到防火墙规则的服务和端口号#使用 firewall-cmd --get-services 可以查看 firewall 支持哪些服务 service=&quo ...
- Bzoj 1588: [HNOI2002]营业额统计(splay)
1588: [HNOI2002]营业额统计 Time Limit: 5 Sec Memory Limit: 162 MB Description 营业额统计 Tiger最近被公司升任为营业部经理,他上 ...
- CSP-S模拟测试 88 题解
T1 queue: 考场写出dp柿子后觉得很斜率优化,然后因为理解错了题觉得斜率优化完全不可做,只打了暴力. 实际上他是可以乱序的,所以直接sort,正确性比较显然,贪心可证,然后就是个sb斜率优化d ...
- 【luogu1325】雷达安装--贪心
题目描述 描述: 假设海岸线是一条无限延伸的直线.它的一侧是陆地,另一侧是海洋.每一座小岛是在海面上的一个点.雷达必须安装在陆地上(包括海岸线),并且每个雷达都有相同的扫描范围d.你的任务是建立尽量少 ...
- P1484 种树——数据结构优先队列
种了一下午的树,终于给搞明白了((多谢各位大神的题解)(题解就不能讲清楚点吗(看不见看不见))): 你有k个树,你可以种在一条直线上,每个位置都有一个价值,如果你把树种在这里就可以获得这个价值,但是条 ...
- Raspberry Pi 4B FTP服务器配置
目录 1. 安装vsftpd并启动 2. 编辑配置文件 3. 重启服务 4. 测试 5. 为Web服务器添加管理员账户,便于通过ftp网站信息 参考资料:树莓派(raspberry pi)学习之安装f ...
- ArcGIS Python 唯一值专题
import arcpy mxd = arcpy.mapping.MapDocument("current") lyr = arcpy.mapping.ListLayers(mxd ...
- 使 nodejs 代码 在后端运行(nohup)
1.代码 nohup node server.js & 说明: nohup 命令对 server.js 进程做了三件事 (1)阻止SIGHUP信号发到这个进程. (2)关闭标准输入.该进程不再 ...