美文网首页
Java内存模型

Java内存模型

作者: 阿懒土灵 | 来源:发表于2018-07-16 19:34 被阅读2次

    前言

    如果把Java比作武功秘籍,那么jvm就是内功心法。只会招式不足以与强敌抗衡,只有将内功修炼到家,结合武功招式才能制敌取胜。
    今天记录的就是jvm内功心法的第一条法则:内存模型


    运行时数据区.png

    图中黄色区域为线程共享,绿色区域为线程隔离数据区。

    程序计数器

    程序计数器为每个线程单独所有,记录线程执行的指令行数。线程与线程之间的程序计数器相互之间不影响。我们称线程独享的这种内存区域为“线程私有”内存。
    如果线程在执行java方法,则这个计数器会记录下正在执行的虚拟机字节码指令的地址;如果是在执行Native方法,则计数器值为空。此内存区域是Java虚拟机没有规定任何OutOfMemoryError的区域。

    虚拟机栈(VM Stack)

    虚拟机栈也是线程私有的,每个线程都会有一个自己的虚拟机栈用来存储方法运行时数据。方法在开始执行时,会创建一个帧栈,并将这个帧栈压入虚拟机栈中。这个帧栈中会存放局部变量表,操作数栈,动态链接和方法出口等信息。一旦一个方法执行结束,对应的帧栈会从虚拟机栈中弹出。待所有方法执行完毕,线程结束,线程对应的虚拟机栈也被回收。可以说,虚拟机栈记录并伴随一个线程从开始到结束。

    局部变量表存放的是方法中定义的基本类型变量和对象引用地址,方法执行完毕,定义的内容也会立即被回收。其中64位长度的long和double类型数据会占用2个局部变量空间,其他数据类型包括引用类型只占用一个。

    如果线程在执行的过程中产生的局部变量等内容超过了虚拟机给虚拟机栈所设置的最大值,则会抛出StackOverFlowError异常,美国一个程序员问答网站就以StackOverFlow来命名。如果虚拟机栈可以动态扩展,但扩展容量不能满足线程要求,则会抛出OutOfMemoryError异常。

    本地方法栈(Native Method Stack)

    虚拟机栈为虚拟机执行java方法服务,而本地方法栈为执行Native方法(非java实现的方法)服务。

    Java堆(Heap)

    Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。Java堆用来存放对象实例,几乎所有的对象实例都在这分配内存,这里同样也是垃圾回收器工作的主要区域,所以也被叫做“GC堆”。

    方法区(Method Area)

    方法区也是线程共享区域,用于存储被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。
    方法区包含一个运行时常量池,该常量池在类加载后会将类的字面量(1.文本字符串 2.八种基本类型的值 3.被声明为final的常量)和符号引用(1.类和方法的全限定名 2.字段的名称和描述符 3.方法的名称和描述符)存入其中。

    对象访问

    最后通过一张图来说明对对象的访问


    对象访问.png

    最后本文内容来自《深入理解Java虚拟机》,做少量增改。

    相关文章

      网友评论

          本文标题:Java内存模型

          本文链接:https://www.haomeiwen.com/subject/hbtipftx.html