Java学习笔记 --- JVM(Java虚拟机)

时间:2022-02-24 09:58:44

Java虚拟机(JVM)是Java应用的运行环境,从一般意义上来讲,JVM是通过规范来定义的一个虚拟的计算机,被设计用来解释执行从Java源码编译而来的字节码。更通俗地说,JVM是指对这个规范的具体实现。这种实现基于严格的指令集和全面的内存模型。另外,JVM也通常被形容为对软件运行时环境的实现。通常JVM实现主要指的是HotSpot。


JVM的内部体系结构分为三部分,

      (1)类装载器(ClassLoader)子系统

                 作用:用来装载.class文件

      2)执行引擎(Execution Engine)

                 作用:执行字节码,或者执行本地方法

      3)运行时数据区

                 方法区,堆,java栈,PC寄存器,本地方法栈


Java学习笔记 --- JVM(Java虚拟机)



第一块: PC寄存器

     PC寄存器是用于存储每个线程下一步将执行的JVM指令,如该方法为native的,则PC寄存器中不存储任何信息。

 第二块:JVM

     JVM栈是线程私有的,每个线程创建的同时都会创建JVM栈,JVM栈中存放的为当前线程中局部基本类型的变量(java中定义的八种基本类型:booleancharbyteshortintlongfloatdouble)、部分的返回结果以及Stack Frame,非基本类型的对象在JVM栈上仅存放一个指向堆上的地址

 第三块:堆(Heap

      Heap是大家最为熟悉的区域,它是JVM用来存储对象实例以及数组值的区域,可以认为Java中所有通过new创建的对象的内存都在此分配,Heap中的对象的内存需要等待GC进行回收。


JVMHeap分为New GenerationOld Generation(或Tenured Generation)两块来

进行管理:

1New Generation

       又称为新生代,程序中新建的对象都将分配到新生代中,新生代又由EdenSpace和两块SurvivorSpace构成,可通过-Xmn参数来指定其大小

2 Old Generation

      又称为旧生代,用于存放程序中经过几次垃圾回收还存活的对象,例如缓存的对象等,旧生代所占用的内存大小即为-Xmx指定的大小减去-Xmn指定的大小。

1)堆是JVM中所有线程共享的,因此在其上进行对象内存的分配均需要进行加锁,这也导致了new对象的开销是比较大的

2)鉴于上面的原因,Sun Hotspot JVM为了提升对象内存分配的效率,对于所创建的线程都会分配一块独立的空间,这块空间又称为TLABThread Local Allocation Buffer),其大小由JVM根据运行的情况计算而得,在TLAB上分配对象时不需要加锁,因此JVM在给线程的对象分配内存时会尽量的在TLAB上分配,在这种情况下JVM中分配对象内存的性能和C基本是一样高效的,但如果对象过大的话则仍然是直接使用堆空间分配

 3TLAB仅作用于新生代的Eden Space,因此在编写Java程序时,通常多个小的对象比大的对象分配起来更加高效,

       但这种方法同时也带来了两个问题,一是空间的浪费,二是对象内存的回收上仍然没法做到像Stack那么高效,同时也会增加回收时的资源的消耗,可通过在启动参数上增加-XX:+PrintTLAB来查看TLAB这块的使用情况。



第四块:方法区域(Method Area)

  (1)方法区域存放了所加载的类的信息(名称、修饰符等)、类中的静态变量、类中定义为final类型的常量、类中的Field信息、类中的方法信息,当开发人员在程序中通过Class对象中的getName、isInterface等方法来获取信息时,这些数据都来源于方法区域,可见方法区域的重要性,同样,方法区域也是全局共享的,在一定的条件下它也会被GC,当方法区域需要使用的内存超过其允许的大小时,会抛出OutOfMemory的错误信息。

  (2)在Sun JDK中这块区域对应的为Permanet Generation,又称为持久代,默认为64M,可通过-XX:PermSize以及-XX:MaxPermSize来指定其大小。


第五块:运行时常量池(RuntimeConstant Pool)

  类似C中的符号表,存放的为类中的固定的常量信息、方法和Field的引用信息等,其空间从方法区域中分配。


第六块:本地方法堆栈(Native Method Stacks)

  JVM采用本地方法堆栈来支持native方法的执行,此区域用于存储每个native方法调用的状态。