Jvm内存模型

来源:互联网 发布:信鸽查询软件下载 编辑:程序博客网 时间:2024/05/16 06:09

这里写图片描述

  1. 程序计数器
    程序计数器(Program Counter Register)是一块较小的内存,记录当前线程执行的字节码的行号。字节码解释器通过改变计数器的值来选取下一条指令,分支、循环、跳转、异常处理、线程恢复等,这些基础功能都需要依赖计数器来完成。Java虚拟机的多线程是通过线程轮流切换实现的,任何时刻一个处理器只执行一个线程中的指令。因此,为了线程切换后可以恢复到原来执行的指令位置,就需要每个线程拥有自己的程序计数器。所以程序计数器这块内存区域是“线程私有”的内存。

  2. 虚拟机栈
    虚拟机栈也是线程私有的内存,其生命周期与线程相同。Java程序的方法在执行的同时会在虚拟机栈中创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。方法从调用到执行结束对应栈帧在虚拟机栈中的入栈到出栈的过程。当程序中请求栈的深度大于虚拟机所允许的的栈深度,将会抛出StackOverflowError异常。不过当前大部分的虚拟机支持虚拟机栈动态扩展,当扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常。

  3. 本地方法栈
    本地方法栈与Java虚拟机栈的作用比较类似,区别在于虚拟机栈为虚拟机执行Java方法服务,本地方法栈为虚拟机调用本地方法(Native Method)服务。
    什么是Native Method
    简单地讲,一个Native Method就是一个java调用非java代码的接口。一个Native Method是这样一个java的方法:该方法的实现由非java语言实现,比如C。这个特征并非java所特有,很多其它的编程语言都有这一机制,比如在C++中,你可以用extern “C”告知C++编译器去调用一个C的函数。
    “A native method is a Java method whose implementation is provided by non-java code.”
    在定义一个native method时,并不提供实现体(有些像定义一个java interface),因为其实现体是由非java语言在外面实现的。,下面给了一个示例:

    public class IHaveNatives{    native public void Native1( int x ) ;    native static public long Native2() ;    native synchronized private float Native3( Object o ) ;    native void Native4( int[] ary ) throws Exception ;}

    本地方法栈也会抛出StackOverflowError和OutOfMemoryError异常。


  4. Java程序中几乎所有的对象和数组都在Java堆上分配,是Jvm管理的一块较大的内存。Java堆在Jvm启动时创建,是所有线程共享的一块内存区域,也是Jvm垃圾回收器管理的主要区域。在Java堆中又被细分为如下几块区域:新生代和老年代,新生代又被细分为Eden区、From Survivor区和To Survivor区。之所以将Java堆按区域划分是为了Jvm能够更好更快的分配和回收内存。通过-Xmx和-Xms可设置虚拟机的堆内存大小。当堆中没有内存可供分配,且堆内存无法扩展,将会抛出OutOfMemoryError异常。

  5. 方法区
    方法区用来存储Jvm加载的类信息、常量、静态变量、即时编译器编译后的代码等。所以很显然方法区也是线程共享的一块内存区域。当方法区中没有内存可供分配,将会抛出OutOfMemoryError异常。