JVM学习之:堆(Heap)和非堆(Non-heap)内存

堆(Heap)和非堆(Non-heap)内存:

堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在 Java 虚拟机启动时创建的。“在JVM中堆之外的内存称为非堆内存(Non-heap memory)”。可以看出JVM主要管理两种类型的内存:堆和非堆。
简单来说堆就是Java代码可及的内存,是留给开发人员使用的;
非堆就是JVM留给 自己用的,所有方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法 的代码都在非堆内存中。

堆内存分配:
-Xms 256m
-Xmx 256m
JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;
JVM最大分配的内存由-Xmx指 定,默认是物理内存的1/4。默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小。

非堆内存分配:
-XX:PermSize 256m
-XX:MaxPermSize 256m
JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;
由-XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。

溢出:

一般情况下出现下列异常可直接定位:
堆溢出:
java.lang.OutOfMemoryError:Java heap spcace
栈溢出:
java.lang.StackOverflowError
方法区溢出:
java.lang.OutOfMemoryError:PermGen space

### JVM 堆内存非堆内存的区别详解 #### 1. 定义与用途 JVM 的 **堆内存** 是运行时数据区域的一部分,主要用于存储类实例数组。它是被所有线程共享的内存区域,在程序启动时创建[^1]。 相比之下,**非堆内存**(也称为元空间或永久代)用于存储加载的类信息、方法代码其他与执行相关的数据。它不直接参与对象实例的存储,而是专注于支持 JVM 自身的操作需求[^3]。 --- #### 2. 存储内容差异 - **堆内存**: 主要用来存放由 `new` 创建的对象实例以及数组。这些对象可以通过垃圾回收器 (GC) 进行自动清理。当堆内存耗尽而无法分配新对象时,会抛出 `OutOfMemoryError` 异常。 - **非堆内存**: 负责保存类的元数据(如字节码)、静态变量、方法区中的常量池等内容。如果非堆内存不足,则同样可能触发 OOM 错误。 --- #### 3. 生命周期管理 - **堆内存**: 受控于 JVM 的垃圾收集机制。未使用的对象会被标记并最终清除掉。开发者可以调整 `-Xms`, `-Xmx` 等参数控制其大小范围。 - **非堆内存**: 不受 GC 影响;它的增长依赖于应用程序动态加载多少个类及其关联资源。从 JDK 8 开始引入了 Metaspace 替代 PermGen,从而解决了固定大小带来的限制问题。 --- #### 4. 性能影响因素 - **堆内存**: 太小可能导致频繁 Full GC ,降低整体效率;过大则增加单次 GC 时间消耗 。因此需要依据实际应用场景合理设定初始值(-Xms) 最大限值 (-Xmx)- **非堆内存**: 如果设置不当可能会导致过多交换到磁盘上或者因为扩展过快占用大量物理 RAM 导致系统不稳定 . --- #### 5. 配置选项对比表 | 参数名 | 功能描述 | 默认行为/建议 | |----------------|-------------------------------------|-------------------------------| | `-Xms` | 设置堆内存最小值 | 根据机器规格适当增大 | | `-Xmx` | 设定的最大可用尺寸 | 不超过总RAM的80% | | `-XX:PermSize`| 初始化非堆(旧版 Permanent Generation)| 已废弃, 使用Metaspace代替 | | `-XX:MaxPermSize`| 指定非堆上限 | 同上 | | `-XX:MetaspaceSize`| 新增项定义MetaSpace起始容量 | 根据项目复杂度自定义 | 注意:上述表格中提到的部分参数仅适用于特定版本下的 JVM 实现情况,请参照官方文档确认最新变更记录。 --- ```java // 示例代码展示如何查看当前 JVM 中各部分内存状态 public class MemoryInfo { public static void main(String[] args){ Runtime runtime = Runtime.getRuntime(); long maxHeapSize = runtime.maxMemory(); // 获取最大堆内存 System.out.println("Maximum Heap Size: "+maxHeapSize+" bytes"); long totalNonHeapMem = ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage().getCommitted();//获取已提交非堆内存总量 System.out.println("Total Non-Heap Committed Memory:"+totalNonHeapMem +"bytes"); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值