zoukankan      html  css  js  c++  java
  • JVM之Java运行时数据区(线程隔离区)

    来源

    JVM会在会在执行Java程序过程中把所管理的内存划分为若干区域,主要包括程序计数器(Program Counter Register),虚拟机栈(VM Stack),本地方法栈(Native Method Stack),堆区(Heap)以及方法区(Method Area)。其中前面3个是线程隔离的数据区,即各个线程均有一份,而后两者是共享区,即所有线程均共享同一份。接下来,我们分别来看一下这些线程隔离的数据区。

    首先是程序计数器

    用于指示一个线程运行到哪个地方了,因为多个线程时,A线程有可能会被挂起从而转向运行B线程,那么等返回执行A线程时,JVM怎么记录A运行到哪里了呢?答案就是程序计数器,因此程序计数器是线程隔离的。那么计数器里存储的是什么东西呢?

    首先我们要大概了解以下字节码文件长什么样子。

    public void F(){
    // 原来的F方法内部的 java 代码,被翻译为下面的类似于汇编语言的指令
        0 xxxx ....
        2 xxxx ....
        4 xx  ...
        5 xxx ...
    }

    代码中的0、2、4、5是字节码的行号,程序计数器存储的正是字节码行号。所以程序计数器的运行原理就很明朗了。当然程序计数器是会被和线程一同创建的。程序计数器是唯一一个没有OutOfMemory异常的区域,因为它不会增加空间,不过随着程序的运行会改变。

    接着是虚拟机栈

    我们常说的堆内存、栈内存的栈区一般指的就是这个,虚拟机栈被用于描述java的方法。每个java方法在执行时会创建一个栈帧(Stack Frame),栈帧的结构包括局部变量表,操作数栈,动态链接和方法出口几个部分。方法执行时创建栈帧,并进入虚拟机栈中,调用结束时,栈帧销毁。每个方法从调用到结束对应栈帧在虚拟机栈的声明周期。虚拟机栈是线程隔离的。

    若栈帧一直增加,超过所允许的深度,将会导致StackOverflowError,可以想象如果方法无限递归没有出口就会导致该异常。

    如果虚拟机栈可以动态扩展但在扩展中无法申请到足够的内存,就会抛出OutOfMemoryError异常。

    栈帧-局部变量表:存放方法参数和方法内部的局部变量,因此,基本数据类型和引用类型的引用就存在栈区中栈帧的局部变量表。(引用类型的对象本身在堆区)

     

    本地方法栈。

    是针对Native的方法的栈,虚拟机栈是其他java方法的栈。不同虚拟机可以自由实现,比如常用的HotSpot虚拟机就选择合并虚拟机栈和本地方法栈。 

  • 相关阅读:
    安卓7.0手机拍照闪退问题解决
    自定义字体TextView
    Android Studio中的CmakeList NDK配置
    动态规划之最长公共子序列(LCS)
    快速排序
    KMP算法实现
    数据结构中的栈
    双向链式线性表(模板实现)
    Android Studio配置OpenCV(非NDK)
    AndroidStudio 1.4配置NDK
  • 原文地址:https://www.cnblogs.com/lbrs/p/11925278.html
Copyright © 2011-2022 走看看