java虚拟机学习笔记1

笔记

1.编译顺序:                 编译器                     虚拟机      虚拟机          java源文件*.java------->字节码*.class------>类装载器--->执行引擎

一个.class文件只能包含一个类或接口。因此.java文件中定义了多少类,编译时就会生成多少.class文件(内部类不算)。

2.java程序可以选择两种方式访问底层系统,由程序员选择:(1).通过java程序调用javaapi调用本地方法,访问底层系统,与平台无关。(2).通过java程序直接调用本地方法,访问底层系统与平台相关。本地方法即操作系统提供的方法。

3.类装载器:装载java编译器编译好的字节码*.class和java api的字节码到方法区。

java有两种类装载器:(1).启动类装载器:系统唯一,属于虚拟机的一部分,用特定语言编写(与虚拟机体层语言相通)使用默认方式装载类,主要用来装载核心类库

。(2).用户自定义类装载器:可有任意多个,用java编写,属于java应用程序的一部分,能被编译成字节码,并被虚拟机所装载。

一个装载器装载一个类及其该类所调用的一切类,使他们相互联系,并形成一个命名空间(name space),每一个类装载器对应一个命名空间。

即java中名字空间的原理。

类装载器成线形排列,自底向上,顶部为启动类装载器。除启动类装载器外,其他类装载器都由用户实例化,用来装载不同的类。当要装载一

个类时,底部的装载器试图将该类交给父装载器装载,而该父类又试图交给他的父类装载,一直向上,直到启动类装载器。若父类装载器无法

装载,则交给子类装载器装载,子类装载能装载的部分,将余下部分交给他的子类,直到底部。如:装载器a,b,c,d,e,f,启动a--->b--->c--->d--->e--->f--->启动当有一个类fun需要被装载时,他会一直上溯到顶部即启动类装载器。如果启动类装载器无法装载fun则交给f装载,f装载能装载的部分,将其

余部分交给e,然后一直这样下去。

如上所述,运行过程中每个类装载器装载的类形成一个运行时包,同一运行时包里的类可以互相访问,但不能访问包外部的类。

4.虚拟机的生命周期:每个java程序都有自己的虚拟机实例,随着程序的产生和消亡而产生与消亡。

5.java程序运行时的内存结构:程序空间分为方法区,堆,java栈,本地方法栈。

(1)方法区存放装载的类数据信息包括:基本信息:每个类的全限定名。每个类的直接超类的全限定名(可约束类型转换)。该类是类还是接口。该类型的访问修饰符。直接超接口的全限定名的有序列表。

每个已装载类的详细信息:运行时常量池:存放该类型所用的一切常量(直接常量和对其他类型,字段,方法的符号引用),它们以数组形式通过索引被访问,是外部调用

与类联系及类型对象化的桥梁。它是类文件(字节码)常量池的运行时表示。(还有一种静态常量池,在字节码文件中)。字段信息:类中声明的每一个字段的信息(名,类型,修饰符)。方法信息:类中声明的每一个方法的信息(名,放回类型,参数类型,修饰符,方法的字节码和异常表)。静态变量到类classloader的引用:即到该类的类装载器的引用。到类class的引用:虚拟机为每一个被装载的类型创建一个class实例,用来代表这个被装载的类。

(2)堆存放所有生成的对象及对象的实例变量。

(3)java栈以帧的形似存放本地方法的调用状态(包括方法调用的参数,局部变量,中间结果等)。每调用一个方法就将对应该方法的方法帧压入

java栈,成为当前方法帧。当调用结束(返回)时,就弹出该帧。编译器将原代码编译成字节码(.class)时,就已经将各种类型的方法的局部变

量,操作数栈大小确定并放在字节码中,随着类一并装载入方法区。当调用方法时,通过访问方法区中的类的信息,得到局部变量以及操作数

栈的大小。

java栈帧(即方法帧)由局部变量区,操作数栈,帧数据区组成。

局部变量区为一个以字为单位的数组,每个数组元素对应一个局部变量的值。调用方法时,将方法的局部变量组成一个数组,通过索引来访问

。若为非静态方法,则加入一个隐含的引用参数this,该参数指向调用这个方法的对象。而静态方法则没有this参数。因此,对象无法调用静态

方法。

操作数栈也是一个数组,但却是通过栈操作来访问。所谓操作数是那些被指令操作的数据。当需要对参数操作时如a=b+c,就将即将被操作的参

数压栈,如将b和c压栈,然后由操作指令将他们弹出,并执行操作,此处由iadd指令将b和c弹出并相加,然后压入操作数栈(一系列均由iadd执

行)然后由i_storex指令将结果弹出,存到索引x指向的局部变量区数组内(此处索引x指向局部变量a)。虚拟机将操作数栈作为工作区。

帧数据区处理常量池解析,异常处理等。

(4)本地方法栈:与调用的本地方法的语言相关,如调用的是一个c语言方法则为一个c栈。本地方法可以回调java方法。若有java方法调用本地方法,虚拟机就运行这个本地方法。在虚拟机看来运行这个本地方法就是执行这个java方法,如果本地方法抛出异常,

虚拟机就认为是这个java方法抛出异常。

(5)执行程序时,通过对象的引用在方法区中查找装载的类,若还没有装载,则查找字节码(类名.class),并将其装载入方法区。在执行过程中,虚拟机会将对象的符号引用(即对象名)替换为直接的指针,以提高访问速度。

(6)因此,大体可以表述为:方法区:存储类包括接口的各种信息,字节码装载到此处。java栈:存储被调用的方法的各种信息,只有调用该方法时,才会将该方法帧压入java栈。堆:存储对象的信息,包括对象的实例变量,但不包括对象的方法。只有调用对象的方法时,才将方法帧压入java栈中。

6.java数据类型:数值类型:浮点类型:float double整数类型:byte,short,int,long,char(int和char可以互换)。引用类型:类类型,接口类型,数组类型。

7.java的引用类型:引用与指针。引用代表被引用的对象,它只是引用对象的代表,并不占用内存,也不能修改。如引用变量没有引用对象,则该引用变量=null。指针存放对象的地址,它是一个变量,可以被修改,和其他变量一样,占用内存。

8.方法区所有线程共享方法区,但为满足线程安全,方法区中每一个类必须被设定为临界资源,即同一时刻某一个类只能被一个线程访问。

9.类标识:由于一个程序可以多次装载同一个类且该类可以存在于不同的名字空间中(即可由不同的装载器装载),因此必须将装载该类的装载器的标识加

上,才能唯一标识一个类。

10.对象对象实例变量存储在堆中,对象符号引用则在常量池,方法属性表等可能出现的地方。通过对象的引用可以访问对象的实例数据和创建该对象

的类的数据。对象的引用指向堆中的对象。实例结构有两种,见书本98页。

当调用对象的方法时,需要进行动态绑定。即,不能根据对象来确定需要调用的方法,而是根据对象的类数据来确定需要调用的方法。此时,

也需要通过对象的引用来访问类数据。动态绑定就是在运行时才绑定,而不是在编译时绑定。

时间: 2024-11-01 09:42:22

java虚拟机学习笔记1的相关文章

java虚拟机学习笔记

笔记 1.编译顺序:                 编译器                     虚拟机      虚拟机          java源文件*.java------->字节码*.class------>类装载器--->执行引擎 一个.class文件只能包含一个类或接口.因此.java文件中定义了多少类,编译时就会生成多少.class文件(内部类不算). 2.java程序可以选择两种方式访问底层系统,由程序员选择:(1).通过java程序调用javaapi调用本地方法,

java虚拟机学习笔记2

笔记 11.数组数组也是类的对象.具有相同类型和维数的数组属于同一个类(不管长度只看维数).数组的长度属于对象实例.多维数组也是一维数组.如二 维数组,即为一个一维数组,该一维数组的每个元素是一个数组的引用.数组和普通对象一样也存储在堆中.数组名为数组的引用,通过索引即数组标号来访问数组内容. 12.异常在java栈帧的帧数据区内保存有针对该方法的异常表的引用.异常表记载了该方法的字节码(*.class)受catch子句保护的范围(即try子句里的 字节码).当某个方法抛出异常时,虚拟机在对应的

《深入Java虚拟机》笔记:指令集 (转)

<深入Java虚拟机>笔记:指令集   指令 含义 iconst_m1 把int型常量-1压入栈中 iconst_0 把int型常量压入栈中 fconst_1 把float型常量1压入栈中 lconst_2 把long型常量2压入栈中 dconst_3 把double型常量3压入栈中 bipush byte1 把byte1转换成int型压入栈中 sipush byte1,byte2 把byte1,byte2组成的short转换成int压入栈中 aconst_null 把空对象压入栈中 ldc

java基础学习笔记之反射_java

反射 反射:将类的属性和方法映射成相应的类. 反射基本使用 获取Class类的三种方法: 类名.class 对象名.getClass() Class.forName("要加载的类名") 根据API写就行了,大致流程就是: 用上述三种方式之一获取特定类的Class类,即该类对应的字节码 调用Class对象的getConstructor(Class<?>... parameterTypes)获取构造方法对象 调用是构造方法类Constructor的newInstance(Obj

java基础学习笔记之泛型_java

泛型 将集合中的元素限定为一个特定的类型. 术语 ArrayList<E> -- 泛型类型 ArrayList -- 原始类型 E -- 类型参数 <> -- 读作"typeof" ArrayList<Integer> -- 参数化的类型 Integer -- 实际类型参数 几点注意: 参数化类型和原始类型相互兼容 ArrayList collection1 = new ArrayList<Integer>();//通过,无warning

Java垃圾收集学习笔记

版权声明:本文为博主原创文章,转载注明出处http://blog.csdn.net/u013142781 (1)除了释放不再被引用的对象,垃圾收集器还要处理堆碎块.请求分配新对象时可能不得不增大堆空间的大小,虽然可以使用的空闲空间是足够的,但是堆中没有没有连续的空间放得下新对象.可能会导致虚拟机产生不必要的"内存不足"错误. (2)使用垃圾收集堆,有一个潜在的缺陷就是加大程序的负担,可能影响程序的性能.因为虚拟机需要追踪哪些对象被正在执行的程序引用,还要动态释放垃圾对象. (3)程序可

深入Java虚拟机读书笔记[8:9]

第八章 连接模型 1. 动态连接和解析 每个类或者接口都编译为独立的class文件,他们之间通过接口(Harbor)符号相互联系,或者与Java API class文件相联系.class文件把所有引用符号保存在常量池,每一个class文件有一个常量池,被装载的类或者接口有一份内部版本的运行时常量池.常量池解析:根据符号查找到试题,把符号替换成直接引用.JDBC通常用forName装载时因为传递第三个参数为true时可以确保类被初始化,静态初始化方法会在DriverManger中被注册驱动程序.

深入Java虚拟机读书笔记[10:20]

第十章 栈和局部变量操作 第十一章 类型转换 第十二章 整数运算 第十三章 逻辑运算 第十四章 浮点运算 第十五章 对象和数组 第十六章 控制流 第十七章 异常 以上一些是操作码相关的内容, 第十八章 finally子句 微型子例程 字节码中的finally子句表现的很像微型子例程.Java方法与微型子例程使用不同的指令集.跳转到微型子例程的指令是jsr或者jsr_w,将返回地址压入栈.执行完毕后调用ret指令.ret指令并不会从栈中弹出返回地址,而是在子例程开始的时候将返回地址从栈顶取出存储在

深入Java虚拟机读书笔记[6:7]

第六章 Java class文件 这章的内容讲的是编译后的class文件格式,我根据内容写了个class文件解析程序. https://github.com/JohnWong/class-file-parser 第七章 类型的生命周期 1. Java虚拟机通过装载.连接与初始化一个Java类型 连接步骤包括验证.准备.解析(可选).在类和接口被装载和连接的时机上,Java虚拟机规范给实现提供了一定的灵活性.但是要求每个类或者接口必须在首次主动使用时初始化.主动使用包括: a) 创建某个类的实例.