JVM运行和类加载过程
JAVA的JVM的内存可分为3个区:堆(heap)、栈(stack)和方法区(method) (该知识点引用 http://www.cnblogs.com/dingyingsi/p/3760730.html)
堆区:
1.存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令)
2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身
栈区:
1.每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中
2.每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
3.栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
方法区:
1.又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。
2.方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。
类加载机制
JVM把class文件加载到内存,并对数据进行校验、解析和初始化,最终形成JVM可以直接使用的Java类型的过程。
加载:
将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区中的运行时二进制数据结构,在堆中生成一个代表这个类的java.lang.class对象,作为方法区类数据的访问入口。这个过程需要类加载器的参与。
链接: 将java类的二进制代码合并到JVM的运行状态之中的过程
验证: 确保加载的类信息符合JVM规划,没有安全方面的问题。
准备:正式为类变量(static变量)分配内存并设置类变量的初始值的阶段,这些内存都将在方法区中进行分配。
解析:虚拟机常量池的符号引用替换为直接引用的过程。
初始化:
初始化阶段是执行类构造器<clinit>()方法的过程。类构造器<clinit>()方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块(static块)中的语句合并产生的。
当初始化一个类的时候,如果发现其父类还没有进行过初始化、则需要先初始化其父类
虚拟机会保证一个类的<clinit>()方法在多线程环境中被正确加锁和同步
当访问一个Java类的静态域时,只有真正声明这个域的类才会被初始化。
例如:
结果:
图解过程:
示例代码:
package com.huang.classLoader;
public class Demo01 {
static {
System.out.println("静态初始化Demo01");
}
public static void main(String[] args){
System.out.println("Demo01的main方法!");
A a = new A();
System.out.println(A.width);
A a2 = new A();
}
}
class A extends A_Father{
public static int width=100;
static {
System.out.println("静态初始化类A");
width = 300;
}
public A(){
System.out.println("创建A的类对象");
}
}
class A_Father{
static {
System.out.println("静态初始化A_Father");
}
}
结果:
静态初始化Demo01 //先加载Demo01
Demo01的main方法! //然后调用main方法
静态初始化A_Father //初始化A的父类
静态初始化类A //然后初始化A
创建A的类对象
300
创建A的类对象 //不需要重新加载类A
类是否初始化:
类的主动引用(一定会发生类的初始化)
new 一个类的对象
调用类的静态成员(除了final常量)和静态方法
使用java.lang.reflect包的方法对类进行反射调用
当虚拟机启动, java Hello ,则一定会初始化Hello类,说白了就是先启动main方法所在的类
当初始化一个类,如果其父类没有被初始化,则会先初始化他的父类
类的被动引用(不会发生类的初始化)
当访问一个静态域时,只有真正声明这个域的类才会被初始化
通过子类引用父类的静态变量,不会导致子类初始化
通过数组定义类引用,不会触发此类的初始化
引用常量不会触发此类的初始化(常量在编译阶段就存入调用类的常亮池中了)
例如:
package com.huang.classLoader;
public class Demo01 {
static {
System.out.println("静态初始化Demo01");
}
public static void main(String[] args) throws ClassNotFoundException {
//主动引用
// new A();
// System.out.println(A.width);
// Class.forName("com.huang.classLoader.A"); //被动引用
// System.out.println(A.MAX);
// A[] as = new A[10];
System.out.println(B.width);//B没有被初始化
}
} class B extends A{
static {
System.out.println("静态初始化B");
}
} class A extends A_Father{
public static final int MAX = 100;
public static int width=100;
static {
System.out.println("静态初始化类A");
width = 300;
}
public A(){
System.out.println("创建A的类对象");
}
}
class A_Father{
static {
System.out.println("静态初始化A_Father");
}
}
JVM运行和类加载过程的更多相关文章
- JVM(五):探究类加载过程-上
JVM(五):探究类加载过程-上 本文我们来研究一个Java字节码文件(Class文件)是如何加载入内存中的,在這個过程中涉及类加载过程中的加载,验证,准备,解析(连接),初始化,使用,销毁过程,并探 ...
- JVM学习笔记——类加载过程
JVM学习笔记——类加载过程 类加载模型——双亲委派模型(Parents Delegation Model)也可称为“溯源委派加载模型” Java的类加载器是一个运行时核心基础设施模块,主要是启动之初 ...
- JVM总括四-类加载过程、双亲委派模型、对象实例化过程
JVM总括四-类加载过程.双亲委派模型.对象实例化过程 目录:JVM总括:目录 一. 类加载过程 类加载过程就是将.class文件转化为Class对象,类实例化的过程,(User user = new ...
- JVM(六):探究类加载过程-下
JVM(六):探究类加载过程-下 上文说了类加载过程的5个阶段,着重介绍了各个阶段做的工作.在本文中,我们对执行加载阶段的主体进行探讨,学习类加载器的模型和逻辑,以及我们该如何自定义一个类加载器. 定 ...
- JVM核心之JVM运行和类加载全过程
为什么研究类加载全过程? 有助于连接JVM运行过程 更深入了解java动态性(解热部署,动态加载),提高程序的灵活性 类加载机制 JVM把class文件加载到内存,并对数据进行校验.解析和初始化,最终 ...
- [jvm学习笔记]-类加载过程
JVM类加载的过程 加载=>验证=>准备=>解析=>初始化 5个阶段所执行的具体动作 加载 在加载阶段,虚拟机需要完成3个事情1.通过一个类的全限定名获取定义此类的二进制字节流 ...
- JVM探究之 —— 类加载过程
1. 类加载是什么 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 与那些在编译时需要进行连 ...
- JVM运行、类加载的全过程
类加载机制:JVM把CLASS文件加载到内存,并对数据进行校验.解析和初始化,最终形成JVM可以直接使用的Java文件. 加载:把class文件字节码加载到内存中,并且将这些静态数据转换成方法区中的运 ...
- JVM核心——JVM运行和类加载全过程
1.类加载全过程 (1)类加载机制 JVM把class文件加载到内存,并对数据进行校验.解析和初始化,最终形成JVM可以直接使用的Java类型的过程. 加载 将class文件字节码内容加载到内存中,并 ...
随机推荐
- Spring @Aspect切面参数传递
Spring @Aspect切面参数传递: Xml: <?xml version="1.0" encoding="UTF-8"?> <bean ...
- Canvas rotate- 旋转
Canvas rotate- 旋转 <!DOCTYPE html> <html lang="en"> <head> <meta chars ...
- 如何解决“BPM导入组织架构出现问题导致系统无法登陆”
遇到问题如图所示↓ 进入H3系统登陆页面. 点击登陆后显示如图错误. 跟踪后显示参数为空.问题描述:通过web service方式进行组织机构导入,只导入ObjectID和Name等共通的6个字段.导 ...
- SoapUI:入门实例
这一章中我们要掌握如下内容: 1) 构建项目: 2) 运行单个请求: 3) 构建测试用例: 4) 接口之间传递参数,组织测试步骤: 5) ...
- android.os.NetworkOnMainThreadException 异常
记下来以后备用 StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectDiskReads() .detectD ...
- cocos2dx内存管理的个人理解
1.一帧开始之后的过程中,将所有执行到的autorelease的对象加入到池中:2.一帧结束之前取出池中的所有对象记作objs,清空池:3.对取出来的objs进行遍历,每个元素进行一次release: ...
- arcpy.mapping常用四大件-MapDocument
arcpy.mapping常用四大件-MapDocument by 李远祥 点开arcpy.mapping的帮助,可以看到其有限的几个类,看起来东西不是很多,但却是非常的使用.由于arcpy定位就是粗 ...
- ContextMenu控件引用以及不用v4包的方法
最近想撸个APP出来玩玩,本想用Yalantis出的SideMenu,结果因为依赖问题放弃了,改用他们家的ContextMenu. 如果你用了v4包 那么问题就比较简单了,直接打开项目中app中的bu ...
- bootstrap-导航总结
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Sublime Text 3 修改插件安装位置【sublime text、插件路径、Data】
直接切入正题,在享受Sublime 插件给我们带来开发效率的同时,有些插件的文件也是很大的,但是插件默认安装的位置是AppData的目录[C:\Users\用户名\AppData\Roaming\Su ...