zoukankan      html  css  js  c++  java
  • jvm内存模型

    JVM的五大内存区域

    1、程序计数器
    2、方法区(也称为永久代,后续被Metaspace取代)
    3、虚拟机栈
    4、本地方法栈
    5、堆

    1、程序计数器

    记录线程的执行位置,线程私有内存
    在多线程的情况下,线程被切换回来的时候能够知道该线程上次运行到哪儿了

    2、方法区

    方法区是所有线程共享的内存区域,用于存储已被虚拟机加载的类信息、常量、静态变量
    放在永久代中经常会出现内存溢出,即PermGen Space异常,所以用元空间取而代之
    元空间直接使用本地内存,理论上电脑有多少内存它就可以使用多少内存,所以不会再出现PermGen Space异常
    java虚拟机对方法区比较宽松,可以选择不实现垃圾收集

    3、虚拟机栈(stack)
    每个线程都有各自的Java虚拟机栈,而且随着线程的创建而创建,随着线程的死亡而死亡.
    Java虚拟机栈会为每一个即将运行的Java方法创建“栈帧”,用于存储局部变量表、操作栈、动态连接、方法返回地址等
    每个方法从开始调用到执行完成的过程,就是栈帧从入栈到出栈的过程
    如果方法A调用了方法B,那么A就会先入栈创建一个栈桢,接着B再入栈成为栈顶,B执行完先出栈,接着A执行完出栈。

    Java虚拟机栈可能出现两种类型的异常:
    1、线程请求的栈深度大于虚拟机允许的栈深度,将抛出StackOverflowError。
    2、虚拟机栈空间可以动态扩展,当动态扩展是无法申请到足够的空间时,抛出OutOfMemory异常。

    4、本地方法栈

    本地方法栈和Java虚拟机栈实现的功能与抛出异常几乎相同
    只不过虚拟机栈是为虚拟机执行Java方法服务,本地方法栈则为虚拟机使用到的本地方法服务.
    线程开始调用本地方法时,会进入一个不再受JVM约束的世界
    本地方法可以通过JNI(Java Native Interface)来访问虚拟机运行时的数据区

    5、堆(heap)

    堆区是所有线程共享的内存区域
    堆是OOM故障最主要的发源地,它存储着几乎所有的实例对象
    通常情况下,它占用的空间是所有内存区域中最大的,但如果无节制地创建大量对象,也容易消耗完所有的空间

    堆的内存空间既可以固定大小,也可运行时动态地调整,通过如下参数设定初始值和最大值
    -Xms256M. -Xmx1024M
    其中,-X表示它是JVM运行参数,ms是memorystart的简称 最小堆容量,mx是memory max的简称 最大堆容量
    但是在通常情况下,服务器在运行过程中,堆空间不断地扩容与回缩,势必形成不必要的系统压力,
    所以在线上生产环境中,JVM的Xms和Xmx设置成一样大小,避免在GC后调整堆大小时带来的额外压力

    堆分成两大块:新生代和老年代(默认空间比例为1:2)
    新生代分为三块:Eden区、From Survivor区和To Survivor区(默认空间比例为8:1:1)
    对象产生之初在新生代,步入暮年时进入老年代,但是老年代也接纳在新生代无法容纳的超大对象
    Survivor区每个对象都有一个计数器,每次YGC都会加1,默认加到15次,就要移送到老年代

    Eden区 -> Survivor 0区 -> Survivor 1区 -> 老年区的过程

    1、所有对象都在伊甸园出生,当伊甸园占满时,开始进行一次Young GC,此次GC会将已存活的对象复制到S0区中
    2、伊甸园区又被占满时,此时又进行一次Young GC,伊甸园存活的对象又复制到S0区。
    3、在若干次Young GC后,幸存区S0也满了,此时Young GC会对伊甸园和幸存区S0的做一次垃圾回收,将两个区存活的对象复制到幸存区S1中,再把伊甸园和S0清空,最后把S1的内存与S0交换,此时S1又腾空了,S0剩下一些老对象。
    4、又经历若干次GC,幸存区S0已经放满了经历过N次GC都回收不了的老对象,此时会将老对象复制到老年代中,腾空伊甸园和幸存区。
    (并非当幸存区被老对象占满才复制到老年代中,当老对象年龄达到15岁,即经历过15次GC都还活着的,也会复制到老年代中)
    (另外伊甸园中如果诞生了一个比幸存区还大的对象,那么该对象回收不了时,也会直接送入到老年代中)

    5、又经历过若干次GC后,老年代也满了,那么此时它会进行一次Full GC。
    6、当执行Full GC后,老年代还是放不下新来的对象时,就会抛出OOM

    堆特点

    Java虚拟机所需要管理的内存中最大的一块,被所有线程共享,在虚拟机启动时创建
    堆是垃圾回收的主要区域,所以也被称为GC堆.
    当线程请求分配内存,但堆已满,且内存已满无法再扩展时,就抛出OutOfMemoryError

  • 相关阅读:
    【NOIP 2003】 加分二叉树
    【POJ 1655】 Balancing Act
    【HDU 3613】Best Reward
    【POJ 3461】 Oulipo
    【POJ 2752】 Seek the Name, Seek the Fame
    【POJ 1961】 Period
    【POJ 2406】 Power Strings
    BZOJ3028 食物(生成函数)
    BZOJ5372 PKUSC2018神仙的游戏(NTT)
    BZOJ4836 二元运算(分治FFT)
  • 原文地址:https://www.cnblogs.com/jis121/p/11045186.html
Copyright © 2011-2022 走看看