JVM的方法区以及JVM运行java文件的过程
2018-01-29 09:17
549 查看
本文整合自http://blog.csdn.net/tuhuolong/article/details/5951589
JVM中的方法区主要存放类的信息等,JVM中的类信息也会被GC,满足以下条件的类就会被GC:
1、该类的堆中所有的实例都被回收。
2、加载该类的类加载器都被回收。
3、该类所对应的java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射机制访问该类的方法。(反射机制比较复杂,以后在好好研究)
类信息:
1、类的完整有效名(包名+类名中间用斜杠隔开,例如java/lang/Object)。
2、直接父类的完整有效名。
3、类的修饰符(public等)。
4、类的直接接口的一个有序列表。
5、类的常量池:保存符号引用及基本数据类型和String类型的常量。
6、成员域信息:
域名、域类、域修饰符,例如public String x,域名为x,域类为String,域修饰词为public。
7、方法信息:
方法名、方法的返回类型、方法的参数列表(包括顺序)、方法的修饰符、操作数栈和局部变量表的大小、异常表。
当我们执行一个方法时,会找到方法区中该方法的信息进行比对,因为方法的参数列表是有序的,所以我们可以重载函数。
8、除了常量以外的所有静态变量。
9、是接口还是类。
10、对类加载器的引用,若一个类是通过用户类加载器加载的,则会保存该加载器的引用,保存在方法区中。
11、对Class类的引用,JVM为每个加载的类都创建一个java.lang.Class的实例,我的理解是这个值相当于索引,帮助我们找到方法区中对应的类信息。
该实例可以通过Class.forName(类名或接口名)获得,调用该函数时,若还未加载该类,JVM会尝试加载对应类,若无法加载该类,则会抛出ClassNotFoundException。通过该实例,我们可以获取存储在方法区中的类信息,相关方法如下:
public String getName();
//返回类的完整名
public Class getSuperClass();// 返回父类的完整名
public boolean isInterface(); //是否是接口
public Class[] getInterfaces(); //获取接口列表
public ClassLoader getClassLoader();// 获取类加载器的引用
方法表
方法表是一组对类实例方法的直接引用,JVM可以通过方法表快速激活实例方法。
下面通过一个实例来了解一下JVM运行java的过程
下面是代码:
class Lava {
private int speed = 5;
void flow() {
}
}
class Volcano {
public static void main(String[] args) {
Lava lava = new Lava();
lava.flow();
}
} JVM通过某种方式加载对应类的class文件(在windows命令行环境下,我们输入java+类名,就是告诉JVM从当前文件下加载该类,windows命令行要先进入到对应文件后执行java指令,否则JVM会误认为java后面的带路径的类名为类名),JVM通过解析方法区的字节码得到main函数的位置,接着执行main函数,在main函数的第一行,我们new了一个Lava,jvm使用指向Volcano常量池的指针找到Lava(查看反编译代码,可以看到指令的后面有一个索引号,JVM根据该索引号来进行查找),发现是一个对
Lava类的符号引用,然后它就检查方法区看lava是否已经被加载了,发现还没有加载该类,于是,JVM开始加载Lava类,从class文件中抽出类信息放在方法区中,于是jvm以一个直接指向方法区lava类的指针替换了常量池中该类的符号引用。以后就可以用这个指针快速的找到lava类了。而这个替换过程称为常量池解析(constant
pool resolution),根据该指针,JVM找到方法区中存储的类信息,得知需要多少堆内存空间,接着执行<init>方法。
JVM中的方法区主要存放类的信息等,JVM中的类信息也会被GC,满足以下条件的类就会被GC:
1、该类的堆中所有的实例都被回收。
2、加载该类的类加载器都被回收。
3、该类所对应的java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射机制访问该类的方法。(反射机制比较复杂,以后在好好研究)
类信息:
1、类的完整有效名(包名+类名中间用斜杠隔开,例如java/lang/Object)。
2、直接父类的完整有效名。
3、类的修饰符(public等)。
4、类的直接接口的一个有序列表。
5、类的常量池:保存符号引用及基本数据类型和String类型的常量。
6、成员域信息:
域名、域类、域修饰符,例如public String x,域名为x,域类为String,域修饰词为public。
7、方法信息:
方法名、方法的返回类型、方法的参数列表(包括顺序)、方法的修饰符、操作数栈和局部变量表的大小、异常表。
当我们执行一个方法时,会找到方法区中该方法的信息进行比对,因为方法的参数列表是有序的,所以我们可以重载函数。
8、除了常量以外的所有静态变量。
9、是接口还是类。
10、对类加载器的引用,若一个类是通过用户类加载器加载的,则会保存该加载器的引用,保存在方法区中。
11、对Class类的引用,JVM为每个加载的类都创建一个java.lang.Class的实例,我的理解是这个值相当于索引,帮助我们找到方法区中对应的类信息。
该实例可以通过Class.forName(类名或接口名)获得,调用该函数时,若还未加载该类,JVM会尝试加载对应类,若无法加载该类,则会抛出ClassNotFoundException。通过该实例,我们可以获取存储在方法区中的类信息,相关方法如下:
public String getName();
//返回类的完整名
public Class getSuperClass();// 返回父类的完整名
public boolean isInterface(); //是否是接口
public Class[] getInterfaces(); //获取接口列表
public ClassLoader getClassLoader();// 获取类加载器的引用
方法表
方法表是一组对类实例方法的直接引用,JVM可以通过方法表快速激活实例方法。
下面通过一个实例来了解一下JVM运行java的过程
下面是代码:
class Lava {
private int speed = 5;
void flow() {
}
}
class Volcano {
public static void main(String[] args) {
Lava lava = new Lava();
lava.flow();
}
} JVM通过某种方式加载对应类的class文件(在windows命令行环境下,我们输入java+类名,就是告诉JVM从当前文件下加载该类,windows命令行要先进入到对应文件后执行java指令,否则JVM会误认为java后面的带路径的类名为类名),JVM通过解析方法区的字节码得到main函数的位置,接着执行main函数,在main函数的第一行,我们new了一个Lava,jvm使用指向Volcano常量池的指针找到Lava(查看反编译代码,可以看到指令的后面有一个索引号,JVM根据该索引号来进行查找),发现是一个对
Lava类的符号引用,然后它就检查方法区看lava是否已经被加载了,发现还没有加载该类,于是,JVM开始加载Lava类,从class文件中抽出类信息放在方法区中,于是jvm以一个直接指向方法区lava类的指针替换了常量池中该类的符号引用。以后就可以用这个指针快速的找到lava类了。而这个替换过程称为常量池解析(constant
pool resolution),根据该指针,JVM找到方法区中存储的类信息,得知需要多少堆内存空间,接着执行<init>方法。
相关文章推荐
- java核心机制——jvm运行以及类加载全过程
- java中对struts中token的使用方法以及jvm学习--策略文件简述
- 关于Java程序中类定义对象的处理,以及类中变量与方法的运行过程
- java的JVM以及java中代码的运行过程
- JAVA开发工具和tomcat互相映射以及JSP文件运行过程和生命周期
- Java项目中读取properties文件,以及六种获取路径的方法
- 设计模式之1.1 再谈反射 以及java当中通过配置文件得到类名字,并生成对象的方法
- 图解Java对象初始化过程以及方法调用
- 图解Java对象初始化过程以及方法调用
- Java打包成jar文件,以及将jar文件导出为exe文件方法汇总
- java -虚拟机(JVM)的运行过程
- 图解Java对象初始化过程以及方法调用
- pb9.0 5507升级8836过程中出现的问题以及升级后工程运行没有反映的解决方法。
- java解压zip或rar压缩文件(有源码和jar包以及对中文乱码的处理方法)
- java写文件时,输出不完整的原因以及解决方法
- java写文件时,输出不完整的原因以及解决方法close()或flush()
- JAVA获取JVM内存使用以及服务器CPU,硬盘使用方法
- Java静态代码块、构造器、静态主方法以及继承后父类代码块的运行顺序
- 非java.util.zip,使用ant.jar制作zip压缩文件,以及相关中文解决方法
- OO中的继承分析,主要分析在编译和运行过程中子类父类的方法、字段和实例化时候在内存中分配和执行的先后,以及两个原则