您的位置:首页 > 运维架构 > 网站架构

JVM体系架构

2015-12-24 10:29 627 查看
JVM Structure Architecture:JVM的体系架构。
a: Run-time Data Areas:运行数据区。
1
pc-register:是线程私有的,每个线程都有自己的程序计数器。

 如果说当前被执行的方法不是native方法,那么pc
寄存器就保存着或者说

 包含着当前正在被执行的JVM虚拟机执行的地址。

 如果说当前被执行的方法是本地方法,那么当前JVM的pc寄存器的值是没有被定义的。
     
     
   
2 JVM Stacks:

 随着线程的创建而创建,销毁而销毁。每一个线程都有一个自己的JVM栈。
 JVM Stack 保存着frames。
 JVM Stack
不能被直接操作,只能弹frame和压frame。frame可能是被heap进行分配的。
 JVM
Stack并不需要内存地址是连续的。
 JVM
stack的大小可以是固定大小也可以随着计算的需要而动态扩展。

 如果JVM栈被指定为一个固定大小,那么每一个JVM
stack的大小将在JVM stack创建时

 独立的进行指定。而且互不干扰。

 如果说每个线程的计算量所需的内存大小比JVMstack
大的话,将会抛出

 stackoverflowerror,比如方法的递归调用中或者死循环时可能会出现。
 如果JVM
stack的大小是设定为可动态扩展的。那么当扩展所需要的内存不够时。

 ,或者说一个线程初始化的时候,由于每个线程都得有个JVM
stack大小。而这个大小也已经超出了所能承载的大小。

 这个时候就会抛出OutOfMemoryError.内存溢出。
 按照我的理解:JVM
stack应该是可以配置的,要么是动态扩展,要么是固定大小。
 当然这点我还不太确定。

3
Heap:堆。当JVM启动的时候就会创建出来。
 是所有JVM
thread所共享的内存区域。他是存放所有类实例以及被分配的数组。

 堆内存可以被gc重新回收。所有的对象都不会被显示的回收。

 都是由垃圾回收器线程进行回收的。
 堆内存也不需要是连续的。

4 Method Area :方法区

 当虚拟机启动的时候创建,供所有的JVM线程共享。用于存放每个类的结果,比如运行常量池

 字段,方法数据,方法代码和构造函数代码等等。

 虽然他是Head即堆内存的逻辑部分,然而简单的实现将不会选择使用垃圾回收和压缩方式
 去处理这块逻辑部分即Method
Area。

 方法区可以是固定大小也可以是动态进行扩展的。他不需要是连续的物理内存空间。
     
     
     
方法区基本上可以认定为GC分代回收中的老年代。
5 run-time constant pool:运行常量池。
 是Method Area的一部分。
     
     
   
     
     
   
 Heap:中有Method Area,Method Area 包含着
runtime constant pool
6 Native Method Stack
     
     
     
存储的是本地方法,依赖于底层C。可以是固定大小,也可以是动态进行扩展的,一般来说接触的比较少。
b:类装载子系统
  1
bootstrap:嵌套在JVM内核当中,是由C++语言写的一套二进制代码。装载JRE/lib/rt.jar.比如system类
     
     
     
     
就是由根加载器加载的。
     
 ExtClassLoader--装载ext目录下的字节码文件。
JRE/lib/ext/*.jar.
     
     
     
 
AppClassLoader--装载classpath下的字节码文件。
     
     
     
  这个可以进行集中管理。
   
  
     
  c:本地方法库
   
  
     
  d: 本地方法接口

     
  e:  执行引擎。
 
 这a-e五大块就是JVM的整个体系架构。在JVM被创建和启动的过程中这五大块分别起的作用是
 
 这个到时候再好好研究下。

frame:帧这个东西。是用来存储数据以及部分结果的同时又充当动态链接的角色,以及包含着方法的返回值。
     
 异常的分发。
   
 方法每调用一次,一个新的frame被创建,

方法执行完成(不管是正常执行完成还是发生错误),frame都会被销毁,一句话:frame的生命周期就是一次方法调用。
当JVM中的线程被创建的时候,同时会有一个JVM
stack被创建的,为每一个线程所独有。
同时JVM stack也会
创建出一个frame出来。每一个frame都有一个本地变量的数组。自己的操作树栈,

以及指向当前方法所在的类的运行时常量池的引用。
   
本地变量数组的大小以及操作树栈的大小是在编译时期就确定好的。同时这两个的大小是由当前执行的方法想关联的
frame进行提供的。
   
因此fram的数据结构的大小仅仅是由JVM的具体实现所决定的,这些数据结构的内存是在方法的执行过程中同时分配的。

也就是说当前执行的方法所在的线程所开辟的JVM
stack内存空间中的frame是在方法的执行过程中进行动态创建和销毁的。
   
在给定的某个线程中,对于正在执行的方法的任何一个时刻,有且仅有一个活动的frame。
 
这个frame我们称之为当前frame,其所在的方法称之为当前方法。当前方法所在的类称之为当前类。 
   
 对本地变量数组和操作数栈的操作都是围绕着当前frame来说的。

如果一个当前方法执行完成或者调用了另外一个方法,那么当前frame停止。
   
 当一个方法被调用的时候,就会创建一个新的frame,从而成为当前frame,控制权就转移到了新的方法上面。
 
当当前方法执行完成的时候,当前frame通过本次方法调用的结果回传回来。如果真的有的话,传给之前的frame。

当前的frame被抛弃,而之前的方法又重新变成了当前的frame。
 
 一句话,当前正在执行的方法就是当前方法,当他调用别的方法的时候,别的方法就成为了当前方法。

当调用返回的时候,执行权又回到最开始的方法那了。
 
 每次线程所创建的thread都是私有的,别的thread不能在访问了。



转发至微博
 



转发至微博
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: