JVM运行数据区-Java堆

Java堆

堆区(Heap区)是JVM运行时数据区占用内存最大的一块区域,每一个JVM进程只存在一个堆区,它在JVM启动时被创建,JVM规范中规定堆区可以是物理上不连续的内存,但必须是逻辑上连续的内存。

1、堆区是线程共享共享的区域,同时也是JVM管理最大的内存区域。

2、JVM规范中描述,所有的对象实例及数组都应该在运行时分配在堆上。而他们的引用会被保存在虚拟机栈中,当方法结束,这些实例不会被立即清除,而是等待垃圾回收。

3、由于堆占用内存大,所以是垃圾回收的重点区域。

堆区的组成

堆区的组成分为年轻代(Young Generation)、老年代(Old Generation),年轻代被分为伊甸区和幸存者区,幸存区又被分为Survivor 0(S0)和Survivor 1(S1)。年轻代和老年代比例为1:2,伊甸区和S0、S1比例为8:1:1,当然这个比例都是可以通过JVM参数设置,不同区域存放的对象不同:

1、伊甸区(Eden) :存放大部分新创建对象。

2、幸存区(Survivor):存放Minor GC 之后,Eden区和幸存区(Survivor)本身没有被回收的对象。

3、老年代:存放Minor GC之后且年龄计数器达到15依然存活的对象、Major GC和Full GC之后仍然存活的对象。

堆空间的大小设置

1、-Xms、-Xmx和-Xmn

Java堆的内存大小是可修改的,默认情况下,初始堆内存为物理内存的1/64,最大为物理内存的1/4。

-Xms:设置初始堆内存,如-Xms64m

-Xmx: 设置最大堆内存,如-Xmx64m

---Xmn: 设置年轻代内存,如-Xmx32m

2、各内存区域比例

年轻代与老年代默认为1:2,可通过-XX:NewRatio参数修改,如-XX:NewRatio=4,即为1:4

伊甸区和S0、S1区默认为8:1:1,可通过-XX:SurvivorRatio参数修改,如-XX:SurvivorRatio=6,通过监测发现设置,以后并不是6:1:1,这是因为Java堆的内存分配策略,关闭内存分配策略,-XX:-UseAdaptiveSizePolicy

3、内存溢出

当JVM无法申请到足够内存给堆空间或者没有足够的空间存储当前堆中的对象,就会出现java.lang.OutOfMemoryError。

验证内存溢出

设置-Xmx128m -XX:+PrintGCDetails(打印GC日志),执行如下程序,创建一个128M数组,该数组既无法在eden区存放,也无法在老年代存放,同时,也会触发一次Full GC,Full GC之后,依然无法存放,抛出OMM异常。

java 复制代码
public class HeapSetDemo {
    public static void main(String[] args) {
        byte[] b = new byte[1024 * 1024 * 128];
    }
}
复制代码
[GC (Allocation Failure) [PSYoungGen: 2007K->856K(38400K)] 2007K->864K(125952K), 0.0007477 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 856K->808K(38400K)] 864K->816K(125952K), 0.0005979 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Allocation Failure) [PSYoungGen: 808K->0K(38400K)] [ParOldGen: 8K->611K(87552K)] 816K->611K(125952K), [Metaspace: 3210K->3210K(1056768K)], 0.0040897 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 0K->0K(38400K)] 611K->611K(125952K), 0.0002508 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Allocation Failure) [PSYoungGen: 0K->0K(38400K)] [ParOldGen: 611K->593K(87552K)] 611K->593K(125952K), [Metaspace: 3210K->3210K(1056768K)], 0.0042290 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at heap.HeapSetDemo.main(HeapSetDemo.java:13)
    ```
相关推荐
2601_962106644 小时前
【Java Set综合实战】商品管理系统 + 图书收藏系统|Product、Book自定义类全套代码
java
RuoyiOffice5 小时前
SpringBoot+Vue3 凭证生命周期设计:审核、过账、冲销与反过账怎样保持账目一致
java·spring boot·事务·springboot3·财务系统·会计凭证·ruoyi office
2601_962106645 小时前
HashMap入门|工号-姓名键值存储、两种遍历方式、根据key/value查
java
czq_26867194875 小时前
Python打卡第46天
开发语言·python
杨凯凡5 小时前
Spring Framework 7 API 版本管理实战:请求头路由、兼容迁移与废弃策略
java·rest api·springframework·spring boot 4·api版本管理
T_Wizard6 小时前
同一个问题写了 4 遍:官方 SDK / HTTP / Spring AI / LangChain4j,到底该选哪个
java·ai编程
hai_android6 小时前
AudioTrack 深度解析:从原理到实战
android·java·kotlin
斯维赤6 小时前
限流、熔断、降级,你真的分得清吗?
java·后端·架构
Evand J7 小时前
【MATLAB例程介绍】(17)永磁同步电机(PMSM)基于自适应无迹卡尔曼滤波(AUKF)的电流噪声在线估计。测量噪声协方差自适应与转速估计对比仿真
开发语言·matlab·卡尔曼滤波·无迹卡尔曼滤波·pmsm·电机滤波
BaiPeter9 小时前
ZPL文件预览
开发语言·c++