Java JVM 内存组成

1) 堆

  运行时数据区域,所有类实例和数组的内存均从此处分配。Java 虚拟机启动时创建。对象的堆内存由称为垃圾回收器 的自动内存管理系统回收。
 堆由两部分组成:

  其中eden+fromspace+tospace也叫年轻代(young),old space叫旧生代.

  其中还有S1,S0(在JDK的自带工具输出中会看到),分别指的是Survivor space,存放每次垃圾回收后存活的对象.

  Old Generation , 主要存放应用程序中生命周期长的存活对象
垃圾回收主要是对Young Generation块和Old Generation块内存进行回收,YG用来放新产生的对象,经过几次回收还没回收掉的对象往OG中移动,
对YG进行垃圾回收又叫做MinorGC,对OG垃圾回收叫MajorGC,两块内存回收互不干涉

2) 非堆内存

  JVM具有一个由所有线程共享的方法区。方法区属于非堆内存。它存储每个类结构,如运行时常数池、字段和方法数据,以及方法和构造方法的代码。它是在 Java 虚拟机启动时创建的。
  除了方法区外,Java 虚拟机实现可能需要用于内部处理或优化的内存,这种内存也是非堆内存。 例如,JIT 编译器需要内存来存储从 Java 虚拟机代码转换而来的本机代码,从而获得高性能。 
  Permanent Generation (图中的Permanent Space) 存放JVM自己的反射对象,比如类对象和方法对象
3) 回收算法和过程
   

 JVM采用一种分代回收 (generational collection) 的策略,用较高的频率对年轻的对象(young generation)进行扫描和回收,这种叫做minor collection,而对老对象(old generation)的检查回收频率要低很多,称为major collection。这样就不需要每次GC都将内存中所有对象都检查一遍。

  当一个URL被访问时,内存申请过程 如下:
A. JVM会试图为相关Java对象在Eden中初始化一块内存区域
B. 当Eden空间足够时,内存申请结束。否则到下一步
C. JVM试图释放在Eden中所有不活跃的对象(这属于1或更高级的垃圾回收), 释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区
D. Survivor区被用来作为Eden及OLD的中间交换区域,当OLD区空间足够时,Survivor区的对象会被移到Old区,否则会被保留在Survivor区
E. 当OLD区空间不够时,JVM会在OLD区进行完全的垃圾收集(0级)
F. 完全垃圾收集后,若Survivor及OLD区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现”out of memory错误”

  对象衰老的过程
  young generation的内存,由一块Eden(伊甸园,有意思)和两块Survivor Space(1.4文档中称为semi-space)构成。新创建的对象的内存都分配自eden。两块Survivor Space总有会一块是空闲的,用作copying collection的目标空间。Minor collection的过程就是将eden和在用survivor space中的活对象copy到空闲survivor space中。所谓survivor,也就是大部分对象在伊甸园出生后,根本活不过一次GC。对象在young generation里经历了一定次数的minor collection后,年纪大了,就会被移到old generation中,称为tenuring。(是否仅当survivor space不足的时候才会将老对象tenuring? 目前资料中没有找到描述)
  剩余内存空间不足会触发GC,如eden空间不够了就要进行minor collection,old generation空间不够要进行major collection,permanent generation空间不足会引发full GC。

例如:jmap -heap 2343,可以看到

Attaching to process ID 2343, please wait…
Debugger attached successfully.
Server compiler detected.
JVM version is 11.0-b16

using thread-local object allocation.
Parallel GC with 8 thread(s)

Heap Configuration:
  MinHeapFreeRatio = 40
  MaxHeapFreeRatio = 70
  MaxHeapSize = 4294967296 (4096.0MB)
  NewSize = 2686976 (2.5625MB)
  MaxNewSize = -65536 (-0.0625MB)
  OldSize = 5439488 (5.1875MB)
  NewRatio = 2 (YG,OG 大小比为1:2)
  SurvivorRatio = 8
  PermSize = 21757952 (20.75MB)
  MaxPermSize = 268435456 (256.0MB)

Heap Usage:
PS Young Generation
Eden Space:
  capacity = 1260060672 (1201.6875MB)
  used = 64868288 (61.86322021484375MB)
  free = 1195192384 (1139.8242797851562MB)
  5.148028935546367% used
From Space:
  capacity = 85524480 (81.5625MB)
  used = 59457648 (56.70323181152344MB)
  free = 26066832 (24.859268188476562MB)
  69.52120375359195% used
To Space:
  capacity = 85852160 (81.875MB)
  used = 0 (0.0MB)
  free = 85852160 (81.875MB)
  0.0% used
~~~~~~~~~~~~~~~~~~~~~~~~~~这三块为上面所说的YG大小和使用情况
PS Old Generation
  capacity = 2291138560 (2185.0MB)
  used = 1747845928 (1666.8757705688477MB)
  free = 543292632 (518.1242294311523MB)
  76.28722062099989% used
~~~~~~~~~~~~~~~~~~~~~~~~~~OG大小和使用情况
PS Perm Generation
  capacity = 108265472 (103.25MB)
  used = 107650712 (102.6637191772461MB)
  free = 614760 (0.5862808227539062MB)
  99.43217353728436% used

你可能感兴趣的:(Java JVM 内存组成)