JVM内存分配
2019-04-23 本文已影响4人
魏树鑫
Java虚拟机运行时数据区.jpg
1. 堆
- 线程共享区域,在虚拟机启动时创建;
- 主要存放对象的实例,Java虚拟机规范中描述:所有的对象实例以及数组都要在堆上分配;
- 垃圾收集器基本采用分代收集法,所以可分为新生代和老年代;
-
新生代
- 占堆大小的1/3,几乎所有的对象创建时分配的空间都在新生代中;
- Minor GC就是作用在新生代中,采用的复制算法;新生代时GC最频繁的区域;
- Eden空间占新生代的8/10,From Survivor和To Survivor各占1/10;
- Eden和From中的对象经过一次Minor GC后,如果对象还活着并且To 空间能容纳下它,将会被复制到To空间中;然后再清理Eden和From空间;
- 每经过一次Minor GC,对象年龄就会+1,默认年龄达到15时,便会复制到老年代中;特别大的对象也有可能直接分配到老年代中;
-
老年代
- 占堆大小的2/3,存放经过多次GC后存活的对象,或者是占用内存较大的对象;
- Full GC是发生在老年代垃圾收集动作,大多数采用标记-清除算法;
- Full GC 发生的次数不会有 Minor GC 那么频繁,并且做一次 Full GC 要比进行一次 Minor GC 的时间更长。
- 标记-清除算法收集垃圾的时候会产生许多的内存碎片 ( 即不连续的内存空间 ),此后需要为较大的对象分配内存空间时,若无法找到足够的连续的内存空间,就会提前触发一次 GC 的收集动作。
2. 方法区
3. 虚拟机栈
- 局部变量表
- 操作数栈
4. 本地方法栈
5. 程序计数器
6. JVM 参数
- 设置初始堆大小
-Xms
如:-Xms256m - 设置最大堆大小
-Xmx
如:-Xmx5120m - 设置新生代大小
-Xmn
通常为 Xmx 的 1/3 或 1/4。新生代 = Eden + 2 个 Survivor 空间。实际可用空间为 = Eden + 1 个 Survivor,即 90% - 设置堆栈大小
-Xss
JDK1.5+ 每个线程堆栈大小为 1M,一般来说如果栈不是很深的话, 1M 是绝对够用了的 - 设置新生代与老年代的比例
-XX:NewRatio
如: –XX:NewRatio=2,则新生代占整个堆空间的1/3,老年代占2/3 - 设置新生代中 Eden 与 Survivor 的比值
-XX:SurvivorRatio
默认值为 8即, Eden 占新生代空间的 8/10,另外两个 Survivor 各占 1/10 - 设置永久代(方法区)的初始大小
-XX:PermSize
- 设置永久代(方法区)的最大值
-XX:MaxPermSize
- 设置打印 GC 信息
-XX:+PrintGCDetails
- 设置虚拟机在发生内存溢出时 Dump 出当前的内存堆转储快照,以便分析用
-XX:+HeapDumpOnOutOfMemoryError