java

位置:IT落伍者 >> java >> 浏览文章

JAVA虚拟机实例学习笔记二


发布日期:2019年01月27日
 
JAVA虚拟机实例学习笔记二

数组

数组也是类的对象具有相同类型和维数的数组属于同一个类(不管长度只看维数)数组的长度属于对象实例多维数组也是一维数组如二

维数组即为一个一维数组该一维数组的每个元素是一个数组的引用数组和普通对象一样也存储在堆中

数组名为数组的引用通过索引即数组标号来访问数组内容

异常

在java栈帧的帧数据区内保存有针对该方法的异常表的引用异常表记载了该方法的字节码(*class)受catch子句保护的范围(即try子句里的

字节码)当某个方法抛出异常时虚拟机在对应的异常表中寻找匹配的catch子句并将控制权交给catch子句中的代码

java执行引擎

实现平台无关性以java方法帧里的操作数栈为中心将局部变量数组当作cpu的寄存器每操作一个数据都要压人操作数栈然后返回至局部

变量区java虚拟机规定强类型转换即低精度可以隐式转换到高精度高精度必须强制转换到低精度

线程

线程即存在于进程中的某个执行体

每个线程必须遵守对象锁定线程等待和通知

对象锁定使线程互斥的访问对象资源等待和通知则是遵守线程合理调度以达到同一个目的java对象通过指令集达到上锁目的同过继承

object类的wait()notify()notifyall()方法来等待和通知当某个线程调用某个对象的wait()方法时该线程被阻塞并加入到该对象的线

程阻塞队列中直到另一个线程调用同一对象的通知方法才能唤醒阻塞队列中的线程

常量池

常量池用来存放类型的各种信息包括类型的各种直接常量和对其他类型字段方法的符号引用

常量池分为两种存储在class字节码中的常量池和存储在方法区中的运行时常量池

常量池以入口形式(类似于中断向量表)出现每个入口都指向一个表表中存储常量的信息但从常量池的入口的标志位就可以判断对应的表

中存储的常量类型

常量池入口以一个标志位开始该标志位指示该常量的类型每个入口对应一个表该表以符号_info结尾表中存放常量的压缩形式

常量池除了存放直接常量外还容纳如下几种符号引用

类和接口的全限定名

字段名称和描述符(该描述符是一个指示字段类型的字符串字段是一个类或接口的类变量或实例变量)

方法名称和描述符(该描述符指示方法返回类型参数类型数量顺序)

运行时虚拟机用常量池的全限定名和方法字段的描述符来建立类与类的关系

常量池仅仅是一个引用和描述符的集合并不接受任何赋值操作

所有对象的创建方法和类变量的调用均要从常量池中获取信息但实例变量的调用从堆里获得(猜想)

符号引用是由虚拟机解析后得到具体的地址来使用

常量池解析就是将常量池中的符号引用替换成直接引用

当要使用某个类的方法或字段时首先从常量池中找到该方法或字段的符号引用然后进行解析找到其物理地址

把代码中出现的各种符号引用类与类的联系进行常量池解析叫做动态连接

常量池结构

常量池由很多狠多的单元组成每一个单元都形如(入口|内容)访问常量池单元时通过索引找到入口然后访问其内容但有时单元的内容也

可能是一个常量池入口(比如类或接口的常量池单元入口包含该类的符号引用即constant_class_info而内容则指向一个

constant_utf_info的常量池单元该单元里存放了该类的全限定名)而直接常量如intfloat等内容处就是常量的值

方法区的结构

方法区存储所有关于类型接口的信息方法区包含

常量池存储类型的直接常量和所有的字段方法其他类型的符号引用(仅仅是引用并不存放具体信息)

字段信息所有声明的字段(包括字段名类型修饰符)

方法信息所有定义的方法(包括方法名返回类型修饰符方法的字节码方法栈帧的大小方法的异常)

类变量信息虚拟机在方法区中为所有类变量分配空间以后的初始化赋值等操作也在方法区中进行以便为所有类实例共享

为提高访问速度虚拟机在方法区中为每个非抽象类设置了一个方法表该表是一个数组每个元素是一个方法的直接引用当类的对象调用

方法时就在方法表中搜索(抽象类没有实例所以不用调用方法所以没有方法表)

堆存放类的实例和数组(包括实例变量指向对应方法区中类数据的引用)

一个例子

class test{

public static void main(string args[])

{

string a=new string(hello)

string b=new string(hello)

string c=hello

string d=hello

}

}

则a==b返回falsec==d返回ture

因为==比较双方是否是同一个对象

首先

string a=new string(hello)

string b=new string(hello)

a和b分别各自新建了hello的对象和引用变量即在堆中有两个hello他们各自的引用是a和b

string c=hello

string d=hello

先建立一个字符串类实例hello再建立两个字符串引用变量c和d然后让c和d都指向开始建立的hello实例因此c和d指向的是同一个对象               

上一篇:一个用java演示的产生图像烟花的算法

下一篇:Java中的中文编码问题