038.[转] JVM启动过程与类加载
From: https://blog.csdn.net/luanlouis/article/details/40043991
Step 1.根据JVM内存配置要求,为JVM申请特定大小的内存空间 ?
使用java.exe 启动JVM
JVM启动时按照其配置要求,申请一块内存,并根据JVM规范和实现将内存划分为几个区域。
所有的类的定义信息都会被加载到方法区。
https://blog.csdn.net/xiangzhihong8/article/details/65657914
配置JVM装载环境
JVM.dll文件的查找和装载
虚拟机参数解析、处理、验证
设置线程栈大小
新建JVM实例
Step 2. 创建一个引导类加载器实例,初步加载系统类到内存方法区区域中;
JVM申请好内存空间后,JVM会创建一个引导类加载器(Bootstrap Classloader)实例,引导类加载器是使用C++语言实现的。
引导类加载器(Bootstrap Classloader)会读取{JAVA_HOME}/jre/lib下的rt.jar(java核心类库)和配置(JVM虚拟机运行时所需的基本系统级别的类),然后将这些系统类加载到方法区内。
rt.jar 如java.lang.String, java.lang.Object等等。
Step 3. 创建JVM 启动器实例 Launcher,并取得系统类加载器ClassLoader
此时,JVM虚拟机调用已经加载在方法区的类sun.misc.Launcher 的静态方法 getLauncher(), 获取 sun.misc.Launcher 实例。
sun.misc.Launcher launcher = sun.misc.Launcher.getLauncher(); //获取Java启动器
ClassLoader classLoader = launcher.getClassLoader(); //获取类加载器ClassLoader用来加载class到内存来;
// 返回 AppClassLoader 实例,AppClassLoader将ExtClassLoader作为自己的父加载器。
sun.misc.Launcher 使用了单例模式设计,保证一个JVM虚拟机内只有一个sun.misc.Launcher实例。
在Launcher的内部,其定义了两个类加载器(ClassLoader),分别是sun.misc.Launcher.ExtClassLoader和sun.misc.Launcher.AppClassLoader,
这两个类加载器分别被称为拓展类加载器(Extension ClassLoader) 和 应用类加载器(Application ClassLoader).
拓展类加载器(Extension Class Loader):
该加载器是用于加载 java 的拓展类 ,拓展类一般会放在 {JAVA_HOME}/jre/lib/ext/ 目录下,用来提供除了系统类之外的额外功能。
拓展类加载器是是整个JVM加载器的Java代码可以访问到的类加载器的最顶端,即是超级父加载器,拓展类加载器是没有父类加载器的?(即bootstrap classLoader?)。
应用类加载器/系统类加载器(Applocatoin Class Loader):
该类加载器是用于加载用户代码,是用户代码的入口。我经常执行指令 java xxx.x.xxx.x.x.XClass , 实际上,JVM就是使用的AppClassLoader加载 xxx.x.xxx.x.x.XClass 类的。
双亲委托模型:应用类加载器将拓展类加载器当成自己的父类加载器,当其尝试加载类的时候,首先尝试让其父加载器-拓展类加载器加载;如果拓展类加载器加载成功,则直接返回加载结果Class<T> instance,加载失败,则会询问是否引导类加载器已经加载了该类;只有没有加载的时候,应用类加载器才会尝试自己加载。
Step 4. 使用类加载器ClassLoader加载Main类
通过 launcher.getClassLoader()方法返回AppClassLoader实例,接着就是AppClassLoader加载我们写的 xxx.xxx.TestMain类的时候了。
当AppClassLoader要加载 xxx.xxx.TestMain.class时,会去查看该类的定义,class文件中有一个叫常量池(Constant Pool)的结构体来存储该class的常量信息。常量池中有CONSTANT_CLASS_INFO类型的常量,表示该class中声明了要用到那些类。.xxx.xxx.TestMain类要想正常工作,首先要能够保证这些其内部声明的类加载成功。所以AppClassLoader要先将这些类加载到内存中。
JVM方法区的类信息区是按照类加载器进行划分的,每个类加载器会维护自己加载类信息;
某个类加载器在加载相应的类时,会相应地在JVM内存堆(Heap)中创建一个对应的Class<T>,用来表示访问该类信息的入口
Step 5. 使用Main类的main方法作为程序入口运行程序
Step 6. 方法执行完毕,JVM销毁,释放内存
038.[转] JVM启动过程与类加载的更多相关文章
- JVM启动过程
JVM启动过程包括:加载.连接.初始化 1.加载:就是将class文件加载到内存.详细的说是,将class文件加载到运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封 ...
- JVM系列(一):jvm启动过程速览
jvm是java的核心运行平台,自然是个非常复杂的系统.当然了,说jvm是个平台,实际上也是个泛称.准确的说,它是一个java虚拟机的统称,它并不指具体的某个虚拟机.所以,谈到java虚拟机时,往往我 ...
- JVM启动过程 类加载器
下图来自:http://blog.csdn.net/jiangwei0910410003/article/details/17733153 package com.test.jvm.common; i ...
- JVM启动过程——JVM之一
JVM是Java程序运行的环境,同时是一个操作系统的一个应用程序进程,因此它有自己的生命周期,也有自己的代码和数据空间. JVM体系主要是两个JVM的内部体系结构分为三个子系统和两大组件,分别是:类装 ...
- 【JVM学习笔记】类加载过程
在Java代码中,类型的加载.连接与初始化过程都是在程序运行期间完成的:提供了更大的灵活性,增加了更多的可能性 JVM启动过程包括:加载.连接.初始化 加载:就是将class文件加载到内存.详细的说是 ...
- JVM 启动参数及原理 转
Java虚拟机(JVM)是Java应用的运行环境,从一般意义上来讲,JVM是通过规范来定义的一个虚拟的计算机,被设计用来解释执行从Java源码编译而来的字节码.更通俗地说,JVM是指对这个规范的具体实 ...
- JVM 启动类加载器2
在运行期,一个Java类是由该类的完全限定名(binary name,二进制名)和用于加载该类的定义类加载器(defining loading)所共同决定的.如果同样名字(即相同的完全限定名)的类由两 ...
- CentOS7 Tomcat 启动过程很慢,JVM上的随机数与熵池策略
1. CentOS7 Tomcat 启动过程很慢 在centos启动官方的tomcat时,启动过程很慢,需要几分钟,经过查看日志,发现耗时在这里:是session引起的随机数问题导致的: <co ...
- JVM学习十五 - (复习)类加载的时机、类加载过程、类加载器
一.类加载的时机 类的生命周期 类从被加载到虚拟机内存开始,到卸载出内存为止,它的整个生命周期包括以下 7 个阶段: 加载 验证 准备 解析 初始化 使用 卸载 验证.准备.解析 3 个阶段统称为连接 ...
随机推荐
- Python连载57- 邮件头和主题、解析邮件
一.添加邮件头,抄送等信息 1.mail["From"]表示发送者信息,包括姓名和邮件 2.mail["To"]表示接收者信息,包括姓名和邮件地址 3.mail ...
- Git 原理简谈
Git 本身是一个对 reference 进行管理的数据库,reference 指的是对原始数据的引用.通过对原始数据的追踪,那么就可以做到对版本的控制.Git 使用一个 DAG 存储了整个的refe ...
- linux服务器JDK1.8环境变量配置
1. 场景描述 软件老王年龄大了,新机器(Linxu)下,配置JDK环境变量老记不住,记录下,有需要的朋友参考下. 2. 解决方案 2.1 上传tar包 ftp上传tar包: jdk-8u181-li ...
- (七十七)c#Winform自定义控件-采样控件-HZHControls
官网 http://www.hzhcontrols.com 前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kww ...
- python高阶函数——sorted排序算法
python 内置的sorted()函数可以对一个list进行排序: >>> sorted([8,3,8,11,-2]) [-2, 3, 8, 8, 11] 既然说是高阶函数,那么它 ...
- Mvc导入
[HttpPost] public void Import() { //获取文件 HttpPostedFileBase fileBase = Request.Files["file" ...
- ES6 解构 destructuring
解构的作用:简化书写长度,提升开发效率. 解构对象 在开发中我们常用到使用ajax请求数据,并且把数据渲染到页面上.可能这个数据返回的对象或数组.例如返回一个obj{name:'zwq',age:18 ...
- Abusing SUDO Advance for Linux Privilege Escalation
Index What is SUDO? Scenario. Sudoer FIle Syntax. Exploiting SUDO zip tar strace tcpdump nmap scp ex ...
- 苹果_公司开发者账号_注册Apple ID
本文所有网站入口为developer.apple.com 注册Apple ID 注意事项:目前注册信息尽量用拼音或英文,姓名格式正确,记住安全问题,出生日期在18岁以上(小于18岁会出现Sorry,y ...
- java web轻量级开发面试教程
最近面试java后端开发的感受:如果就以平时项目经验来面试,通过估计很难——再论面试前的准备 在上周,我密集面试了若干位Java后端的候选人,工作经验在3到5年间.我的标准其实不复杂:第一能干活,第二 ...