美文网首页
jvm内存模型及GC记录

jvm内存模型及GC记录

作者: AlanSun2 | 来源:发表于2019-05-20 14:20 被阅读0次

    在jvm中有一块非常重要的区域,就是jvm运行时数据区。今天对该区域做下总结和记录:

    在讨论jvm运行时数据区前,先说下jvm,jvm是一套规范,并不是实现,现在它的实现主要有hotspot(oracle),JRocket(oracle),J9(IBM)

    正题

    jvm运行时数据区总共分为5块:堆,方法区,java栈,本地方法栈,程序计数器。这些都是jvm规范,并不是实现,实现我会在下一节对hotspot重点讲解。

    jvm运行时数据区
    1. 堆

    线程共享,存放运行时产生的对象。在虚拟机启动时创建。

    2. 方法区

    线程共享,存放类型信息

    3. 程序计数器

    线程私有,是一块较小的内存空间,指示当前线程所执行的字节码行号。如果执行的是本地的方法,那么这个计数器值为空。

    4. java栈

    线程私有,生命周期与线程相同。每个java方法在栈里都是一个栈帧。栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每个方法在调用到执行完成的过程,就对应着一个栈帧在虚拟机中入栈到出栈的过程。
    局部变量表存放了各种基本类型、对象引用、和returnAddress类型(指向一条字节码指令的地址)。

    5. 本地方法栈

    原理和java栈类似,是java调用其他语言的方法的存放区。

    可以把每个java栈的大小适当调小一点,减少内存的使用量来提高系统的并发量。但是当栈空间调小以后,又会引发方法调用深度的的问题(StackOverFlowError)。这个需要根据实际情况而定。

    jvm的一个实现,Hotspot

    Hotspot是jvm中一个使用最广泛的实现。

    方法区的实现
    • 在jdk1.8之前方法区的采用永久代来实现
    • 从jdk8开始使用元数据空间来实现方法区

    这两个实现最重要的区别就是元数据空间并不在虚拟机中,而是使用本地内存。

    堆的分类

    Hotspot中堆被分为了新生代和老年代。更细一点划分新生代又可划分为Eden区和2个Survivor区(From Survivor和To Survivor)。平时我们所说的GC就发生在这。

    • Eden:新创建的对象存放在Eden区

    • From Survivor和To Survivor:保存新生代gc后还存活的对象。(使用复制算法,导致有一个Survivor空间浪费)Hotspot虚拟机新生代Eden和Survivor的大小比值为4:1,因为有两个Survivor,所以Eden:From Survivor:To Survivor比值为8:1:1。

    • 老年代:对象存活时间比较长(经过多次新生代的垃圾收集,默认是15次)的对象则进入老年代。
      当堆中分配的对象实例过多,且大部分对象都在使用,就会报内存溢出异常(OutOfMemoneyError)。


    字符串常量存放位置,jdk1.7之前存在在永久代,1.7及之后存放在堆内存。


    未完待续

    相关文章

      网友评论

          本文标题:jvm内存模型及GC记录

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