zoukankan      html  css  js  c++  java
  • 【JVM学习笔记一】JVM内存分布

    Overview

    学习JVM首先需要了解一下JVM管理的内存是如何分布的,在看了《深入理解Java虚拟机》和一些博文之后,我准备自己记录一下学习的过程。

    下图是JVM中运行时数据区的大致示意图,可以看到主要分为两种内存区域,一种是线程私有的内存区,另一种是所有线程共享的区域。下面会详细描述每个区域存储哪些数据。

    程序计数器

    我们知道JVM是通过解释Java编译之后的字节码来执行程序的,那么JVM是怎么知道执行到哪一行字节码了呢?答案就是通过程序计数器来指示当前线程执行的字节码行号。我认为应该是JVM模仿CPU中的程序计数器来设计的。

    • 需要注意的是每个线程都有自己私有的一个程序计数器,从而保证互相不干扰。同一时刻一个CPU内核只能执行一个线程上的代码。

    • 当执行Java方法时程序计数器会起作用,但是执行Native方法时计数器值为空。

    • 程序计数器区是JVM内存区中唯一一个不会触发OutOfMemory(OOM)异常的区域。

    Java虚拟机栈

    Java虚拟机栈也是专属于线程的内存区域,在线程执行每个方法时都会创建一个栈帧(Stack Frame),栈帧中存放了局部变量表、操作数栈、动态链接(reference)等信息。

    • 当线程请起的栈深度大于虚拟机允许的最大深度,就会出发Stackoverflow异常;
    • 如果虚拟机栈允许动态扩展,当无法申请足够内存时会出发OOM异常。

    本地方法栈

    本地方法栈与Java虚拟机栈的区别就是Java虚拟机栈为Java方法服务,而本地方法栈服务的是Native方法。有些虚拟机会把二者合一,比如HotSpot VM。本地方法栈也会抛出Stackoverflow和OOM异常。

    堆是JVM中最大的一块内存区域,主要是用来存放对象实例,几乎所有的对象实例都在堆上分配。

    堆也是垃圾收集器(GC)管理的主要工作区域。GC基本采用分代回收算法,所以Java堆可以分为新生代(Young Generation)和老年代(Old Generation),更细一点可以分为Eden、From Survivor空间和To Survivor空间。

    Young Generation:主要是用来存放新生的对象,也是GC最经常发生的区域。

    Old Generation:主要存放应用程序中生命周期长的内存对象,GC较少发生。

    可以通过设置VM参数来扩展堆的大小:

    • -Xms:初试堆大小
    • -Xmx:堆最大大小
    • -XX:NewSize=n :设置年轻代大小
    • -XX:NewRatio=n: 设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4
    • -XX:SurvivorRatio=n :年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5

    堆也可以抛出OOM异常。

    方法区

    方法区和堆一样是所有线程共享的内存区域,用于存储虚拟机加载的类信息、metadata、常量、静态变量、JIT编译器编译后的代码等数据,一般称为永生代(Permanent Generation),GC基本不会对永生代进行垃圾收集。

    当方法区无法满足内存分配需求时也会抛出OOM异常。

    运行时常量池

    运行时常量池是方法区中的一部分,用于存放编译期生成的字面量和符号引用。

    题外话

    直接内存

    直接内存不属于JVM管理的内存区域,但是也被频繁使用,其中最典型的例子就是NIO库,在之前一篇文章介绍过。NIO引入了channel和buffer,使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteBuffer对象来作为堆外内存的引用进行操作。这样避免了数据在Java堆和Native堆之间的复制,从而提升性能。

    同样,该区域也会抛出OOM异常。

  • 相关阅读:
    hdu-4638
    一个简单的询问
    CoderForces-617B
    HYSBZ-2002弹飞绵羊
    邻接表
    CoderForces-913-C
    CoderForces-913D
    CoderFocers-620C
    CoderForces-375D
    HDU-6119
  • 原文地址:https://www.cnblogs.com/puyangsky/p/6208370.html
Copyright © 2011-2022 走看看