java虚拟机的结构

java

Posted by Honson on January 9, 2019

java虚拟机的结构

  1. 类加载子系统
    负责从文件系统或网络中加载class信息,加载的信息存放的一块称为方法区的内存空间。除了类信息,方法区还存放运行时常量池信息。(这部分的信息是Class文件中的常量池部分的内存映射)
    
  2. java堆
    java堆在虚拟机启动的时候建立,他是主要的内存工作区域,几乎所有的java对象都放在堆内存中。堆空间对线程是共享的
    
  3. NIO库
    NIO库允许java程序使用直接内存。直接内存是在java堆外直接详向系统申请内存区间。直接内存的读取速度会由于java堆内存。因此在出于性能考虑,频繁读写的可以使用直接内存。由于直接内存在堆内存外,因此他的大小不受最大最小堆内存的限制。只受限于系统分配的内存大小。
    
  4. 垃圾回收
    垃圾回收是java虚拟机最重要的组成部分,垃圾回收会对堆内存,方法区,直接内存进行回收。这个过程是自动的
    
  5. java栈
    每一个java虚拟机线程都有一个私有的java栈。一个线程栈在线程创建的时候会被创建。java栈保存帧信息,保存局部变量、方法参数。与方法的调用返回密切相关。 本地方法栈与java方法栈非常类似,java方法栈在java方法调用时调用,本地方法栈在本地方法调用时被调用
    

    JAVA方法是由JAVA编写的,编译成字节码,存储在class文件中 本地方法是由其它语言编写的,编译成和处理器相关的机器代码本地方法保存在动态链接库中,即.dll(windows系统)文件中,格式是各个平台专有的JAVA方法是与平台无关的

  6. PC寄存器
    寄存器是每个线程的私有空间,java虚拟机会为每个java线程创建一个PC寄存器。在任意时刻java线程执行的方法被称为当前方法,如果当前方法不是本地方法PC寄存器就会指向当前正在被执行的指令。如果是本地方法那么PC寄存器的值就是undefined
    
  7. 执行引擎
    最重要的组件,负责执行虚拟机字节码
    
栈的结构

每次函数调用都会产生对应的栈帧,从而占用一定的栈空间,当栈空间不足时就会函数就无法进行了,申请栈深度大于最大栈深度时就会抛出StackOverError栈溢出错误

局部变量表
	用于保存函数参数以及局部变量,局部变量只在当前函数中有效,当函数调用结束后会随着函数帧的销毁而销毁
操作数栈
	用于保存计算过程的中的中间结果,同时作为的计算过程中的临时变量储存
帧数据区
	常量池解析、正常方法返回和异常处理,大部分java字节码指令都需要进行常量池的访问,在帧数据区还保存着大量的常量池的指针。 当函数返回或者出现异常时,虚拟机必须恢复调用者的函数栈帧,并让调用者函数继续执行下去。对于异常处理虚拟机必须有一个异常处理表,当方法出现异常时虚拟机就会查找出类似的异常表进行处理
栈上分配
	java虚拟机提供的一项优化技术,对于私有的对象,可以将他们打散分配到栈上而不是堆上。这样就可以在函数销毁后,对象也随之销毁,不用垃圾回收介入
栈上分配要进行技术分析如:

下面代码显示了一个逃逸对象

private static User u;
public static void alloc(){
   u=new User();
   u.id=5;
   u.name="geym";
}

非逃逸对象,这种情况是分配在

pubilc static void alloc(){
   User u=new User();
   u.id=5;
   u.name="haha";
}
	-server -XX:+DoEscapeAnlysis -XX:+PrintGC -XX:-UseTLAB -XX:+EliminateAllocations 
	这里使用了-server执行程序,因为在server模式下,才可以启用逃逸分析。参数-XX:+DoEscapeAnalysis 启用逃逸分析