美文网首页
运行时数据区

运行时数据区

作者: 一萍之春 | 来源:发表于2019-02-15 12:05 被阅读34次

    运行时数据区

    事实上,JVM在执行Java代码时都会把内存分为几个部分,即数据区来使用,这些区域都拥有自己的用途,并随着JVM进程的启动或者用户线程的启动和结束建立和销毁。如下图大家应该很熟悉。


    运行时数据区

    程序计数器(Program Counter Register)

    它所占用的内存空间比较小,主要用于当前线程所执行的字节码的行号指示器,其实很好理解因为当我们线程切换的时候需要记录当前线程执行到什么地方,下一步该做什么,其实可以类比一下操作系统中的程序计数器。由它的作用可想而知它是我们线程私有的一个数据区。
    可能触发的异常:程序计数器是在JVM规范中唯一个不会触发OutOfMemoryError(内存泄露错误,下文简称OOM)。

    虚拟机栈(VM Stack)

    它的数据结构也就是我们常说的栈结构。每个方法在执行的同时都会开辟一段内存区域用于存放方法运行时所需的数据,成为栈帧,一个栈帧包含如:局部变量表、操作数栈、动态链接、方法出口等信息。其中局部变量表是在编译期分配空间的,运行期间是不变的。故而它也是线程私有的。也因为它是栈的结构由栈先进后出的特性方法的执行被调用的先执行完后执行调用方。
    可能触发的异常:
    1、如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常。
    2、如果在动态扩展内存的时候无法申请到足够的内存,就会抛出OOM异常。单线程下一般不可能被触发,多数在多线程的情况下被触发OOM异常。
    设置JVM参数:"-Xss128k"(栈大小为128K)

    本地方法栈

    本地方法栈和虚拟机栈类似,不同的是虚拟机栈服务的是Java方法,而本地方法栈服务的是Native方法。在HotSpot虚拟机实现中是把本地方法栈和虚拟机栈合二为一的,同理它也会抛出StackOverflowError异常和OOM异常。

    堆(heap)

    对于堆,Java程序员都知道对象实例以及数组内存都要在堆上分配。堆不再被线程所独有而是线程所共享的一块区域,它的确是用来存放对象实例,也是垃圾回收GC的主要区域。实际上它还能细分为:新生代(Young Generation)、老年代(Old Generation)。对于新生代又分为Eden空间、From Survivor空间、To Survivor空间。。
    可能触发的异常:堆申请的空间过大并且每个对象都有GC Root的指向不能被回收,会抛出OOM异常。
    设置JVM参数:"-Xms128M"(表示初始堆大小128M)、"-Xmx2048M"(表示最大堆大小2048M)

    方法区(Method Area)

    它存储的是已被虚拟机加载的类信息、常量(从JDK7开始已经移至堆内存中)、静态变量等数据。它还有一个外号就是永久代(Permanent Generation)但是7及以后都在去掉永久代。在JDK8则是纯粹取消了方法区这个概念,取而代之的是”元空间(Metaspace)
    可能触发的异常:当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常。
    设置JVM参数:"-XX:MaxPermSize=256M"(表示方法区最大内存为256M)在JDK8中变为了"-XX:MetaspaceSize"和"-XX:MaxMetaspaceSize"来设置元空间的大小了。

    相关文章

      网友评论

          本文标题:运行时数据区

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