您的位置:首页 > 其它

jvm 内存管理-运行时数据区域

2018-07-16 14:56 162 查看

 jvm在执行java程序时,会把所管理的内存分为几个不同的数据区域,每个区域有不同的用途,以及创建销毁的时间。

    <java虚拟机规范>规定,JVM所管理的内存包括几个运行时数据区域

    方法区

            被所有线程共享,用于存储被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码,

            方法区无法满足内存分配需求,outofmemoryerror错误

            运行时常量池,方法区的一部分,存放编译器生成的字面量和符号引用,运行期间可以将新的常量放入池中,比如String的intern().

    虚拟机栈

            线程私有,生命周期与线程相同,此区域描述java方法执行的内存模型,每个方法执行时都会创建一个栈帧,用于存储局部变量表(基本数据类型,对象引用),操作数栈,方法出口等

 

  1. 线程私有区域
  2. 线程栈深度大于虚拟机允许的深度,StackOverflowError错误
  3. 虚拟机栈可动态扩展,如果扩展时,无法申请到足够内存,outofmemoryerror错误

     本地方法栈

            与虚拟机栈类似,虚拟机栈执行java方法(字节码服务),本地方法栈为Native方法服务,Sun HotSpot将本地方法栈和虚拟机栈合二为一。本地方法栈也会有StackOverflowError和outofmemoryerror

     堆

            此区域是JVM管理内存最大的一块,被所有线程共享,该区域唯一目的就是存放对象实例,所有对象实例和数组都要在堆上分配,随着JIT编译器发展,逃逸分析技术成熟,栈上分配,标量替换会导致所有对象分配在堆上变得不绝对。()

     java堆是垃圾收集管理的主要区域,由于现在收集器基本采用分代收集算法,java堆可分为新生代,老年代。

    java堆可以处于不连续的内存空间,如果堆中没有内存完成实例分配,并且堆无法扩展,outofmemoryerror错误,可以通过(-Xms  -Xmx控制)

 

    程序计数器

            一块较小的内存空间,可以当作当前线程所执行的字节码的行号指示器。字节码解释器就是通过改变这个计数器的值选取需要下一个需要执行字节码指令,分支,循环,跳转,异常处理,线程恢复都依赖程序计数器。

 

  1. 如果线程正在执行的是Java 方法,则这个计数器记录的是正在执行的虚拟机字节码指令地址

  2. 如果正在执行的是Native 方法,则这个技术器值为空(Undefined)

  3. 此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域

  4. 线程私有区域

hotSpot 中,不区分虚拟机栈和本地方法栈。

 

本文内容主要是学习周志明老师的《深入理解Java虚拟机》一书的学习笔记,仅作学习巩固整理知识点使用,在此感谢周老师。

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