2.4 堆
对一个进程而言,堆和方法区都是唯一的。在这个进程里面的线程是共享堆和方法区的。对于一个线程而言,程序计数器、虚拟机栈和本地方法栈是不共享的。
堆是java内存管理的核心区域,在JVM启动的时候就被创建,其空间大小也确定了。是JVM最大的一块内存空间,在物理上不连续的内存空间,在逻辑上是连续的。堆内存是可以调节的(-Xmx(堆空间最大内存)和-Xms(堆区起始内存))。
- 所有对象实例及数组都应当在运行时分配在堆上。
- 数组和对象可能永远不会存储在栈上,因为栈帧存储引用,这个引用指向对象或者数组在堆中的位置。
- 在方法结束后,堆中对象不会马上被移除,只有在垃圾收集的时候才会被移除
- 堆是GC(垃圾收集器)执行垃圾回收的重点区域。
内存细分
现代垃圾收集器大部分都基于分代收集理论设计
Java7之前:新生区+老年区+永久区
java8之后:新生代 +老年代+元空间
堆空间大小设置
-Xms:设置堆空间起始大小-X:jvm运行参数ms:memory start
-Xmx:设置堆空间最大内存
一旦堆空间中内存大小超过 -Xmx所指定的最大内存时,会抛出OOM异常。
通常设置 -Xms和 -Xmx两个参数配置相同的值,目的是能够在java垃圾回收机制清理完堆内存后不需要重新分隔计算堆区大小,从而提高性能。
默认情况:起始内存大小:物理内存/64,最大内存大小:物理内存/4
新生代和老年代
存储在JVM中的java对象有两类:
- 生命周期较短的瞬时对象
- 生命周期较长的,极端点可以和JVM的生命周期保持一致
配置新生代与老年代在堆中占比:(一般不修改参数)
- 默认:
-XX:NewRatio=2表示新生代占1 (1/3),老年代占2。 - 可以修改
-XXwRatio=4表示新生代占1 (1/5) 老年代占4
-XX: -UseAdaptiveSizePolicy:关闭自适应内存分配策略
-XX:SurvivorRatio=8:伊甸园区:幸存者0区:幸存者1区=8:1:1
-
几乎所有的对象都是在伊甸园区被new出来的
-
绝大部分对象都被销毁在新生代(80%)
使用 -Xmn:设置新生代最大内存大小(一般使用默认值)(与上面冲突了,以这个为准)
对象分配的一般过程
重点:
- 幸运者0区(s0)和幸运者1区(s1):复制之后有交换,谁空谁为to
- 关于垃圾回收:频繁在新生代收集,很少在老年代收集,几乎不在元空间收集。