java 所有虚拟机_Java虚拟机

3.5程序计数器

对于一个运行中的Java程序而言,其中的每一个线程都有它自己的PC(程序计数器),在线程启动时创建。大小是一个字长。当线程执行某个Java方法时,PC的内容总是下一条将被指向指令的“地址”。如果该线程正在执行一个本地方法,那么此时PC的值为”undefined”。Java栈

3.6Java栈

每当启动一个线程时,Java虚拟机都会为它分配一个Java栈,Java栈也帧为单位保存线程的运行状态,虚拟机只会直接对Java栈执行两种操作:以帧为单位的压栈和出栈。

某个线程正在执行的方法被称为该线程的当前方法,当前方法使用的栈帧称为当前帧,当前方法所属的类称为当前类,当前类的常量池称为当前常量池,在线程执行一个方法时,它会跟踪当前类和当前常量池。

每当线程调用一个方法时,虚拟机都会在该线程的Java栈中压入一个新帧,而这个新栈自然就成为当前帧。在执行这个方法时,它使用这个帧来存储参数、局部变量、中间运算结果等等数据。

Java栈上的所有数据都是数据都是此线程私有的。

3.7栈帧

栈帧由三部分组成:局部变量区、操作数栈和帧数据区。局部变量区和操作数栈的大小要视对应的方法而定,编译器在编译器时就确定的确定了这些值并放在class文件中。帧数据区的大小依赖于具体的实现。

当虚拟机调用一个方法时,它从对应类的类型信息中得到此方法的局部变量区和操作数栈的大小,并据此分配栈帧内存,然后压入Java栈中。

局部变量区:Java栈帧的局部变量区被组织为以一个字长为单位、从0开始计数的数组。字节码指令通过从0开始的索引来使用其中的数据。

局部变量区对应方法的参数和局部变量。编译器首先按声明的顺序把这些参数放入局部变量数组。

在java中,所有的对象都按引用传递,并且都存储在堆中,永远都不会在局部变量区或操作数栈中发现对象的拷贝,只会有对象的引用。

操作数栈:操作数栈也是被组织为一个字长为单位的数组。但它不是通过索引来访问,而是通过标准的栈操作——压栈和出栈来访问的。

帧数据区:支持解析常量池解析、正常方法返回以及异常派发机制。每当虚拟机要执行某个需要用到常量池数据的指令时,它都会通过帧数据区中指向常量池的指针来访问它。常量池中对类型、字段和方法的引用在开始时都是符号。当虚拟机在常量池中搜索时,如果遇到类、接口、字段或者方法的入口,假若它们仍然是符号,虚拟机那时候才会进行解析。

3.8执行引擎

指令集:方法的字节码流是由Java虚拟机的指令序列构成的。每一条指令包含一个单字节的操作码,后面跟随0个或多个操作数。操作码本身就已经规定了它是否需要跟随操作数,以及如果有操作数它是什么形式的。当虚拟机执行一条指令的时候,可能使用当前常量池中的项、当前帧的局部变量中的值,或者当前帧操作数栈顶端的值。

执行技术:解释、即时编译、字适应优化、芯片级直接执行。

Hotspot虚拟机就采用了自适应优化。自适应优化虚拟机开始的时候对所有的代码都是解释执行,但是它会监视代码的执行情况。大多数程序花费80%-90%的时间来执行10%-20%的代码。虚拟机可以意识到那些方法是程序的热区——就是那10%-20%的代码,他们占整个执行时间的80%-90%。当自适应优化的虚拟机判断出某个特定的方法是瓶颈的时候,它启动一个后台线程,把字节码编译成本地代码,非常仔细的优化这些本地代码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值