初探JVM堆内存

本文探讨了JVM管理的内存中最重要的部分——堆内存。堆内存是所有线程共享的区域,主要用于分配大部分对象的内存空间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

java虚拟机在运行Java程序的时候会将其内存划分为好几个不同的数据区域。

对大多数应用来说,堆内存应该是虚拟机管理的内存中最大的一块。java堆是可以被线程共享的区域,几乎所有的对象都在堆上进行内存空间的分配.


堆内存被划分成3块: 
1.永久代 JVM的方法区
用于存放静态类型数据,该块对垃圾回收没有什么影响。
2.新生代
所有新建的对象首先存放在新生代,目的在与尽快回收那些生命周期短的对象。
新生代主要由Eden和Survivor Space构成, 大小统过-Xmn指定, 一般将Survivor区分成S1,S2两块。Eden与Survivor Space的默认比例为8:1:1, 可以通过-XX:SurvivorRatio指定。
3.老年代
在新生代中经历了N个周期还没被回收的对象就会被复制到老年代,因此可以认为存放的都是一些生命周期较长的对象。


当对象在新生代存活次数超过上限时(可通过-XX:MaxTenuringThreshold配置, 对象存活的次数)就会被复制到老年代。相当于是Eden+某个S中存活下来的对象大于另一个S中的空间, 新生代中的对象就会被复制到老年代。


根据Java虚拟机规范的规定,Java堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可。在JVM运行时,可以通过配置以下参数改变整个JVM堆的配置比例。


1.JVM运行时堆的大小


  -Xms堆的最小值


  -Xmx堆空间的最大值


2.新生代堆空间大小调整


  -XX:NewSize新生代的最小值


  -XX:MaxNewSize新生代的最大值


  -XX:NewRatio设置新生代与老年代在堆空间的大小


  -XX:SurvivorRatio新生代中Eden所占区域的大小


3.永久代大小调整


  -XX:MaxPermSize
不管以什么形式来划分堆,其储存的都是对象实例,划分的目的也是为了更好的回收内存或更快的分配内存。


JVM堆内存是Java虚拟机管理的内存中最大的一块区域,主要用于存放运行时创建的对象实例。堆内存由所有线程共享,并且在JVM启动时被创建。根据《Java虚拟机规范》,堆可以细分为几个不同的区域,这些区域随着JVM版本的发展有所变化。 ### 堆内存的主要组成部分 #### 1. 新生代(Young Generation) 新生代是堆内存的一部分,专门用于新创建的对象。大多数对象在这个区域被分配,并且它们的生命周期通常较短。新生代又被划分为三个部分:一个Eden区两个Survivor区(FromTo)[^2]。 - **Eden区**:当对象首次被创建时,通常会被放置在这里。 - **Survivor区**:包含两个大小相等的部分,即From空间To空间。这两个空间用来存储从Eden区经过垃圾回收后仍然存活下来的对象。 #### 2. 老年代(Old Generation 或 Tenured Generation) 老年代存放的是经历了多次垃圾收集后依然存活的对象。这些对象由于其较长的生命周期而被认为更有可能继续存在下去。如果新生代中的对象足够“长寿”,或者直接大对象会被直接分配到老年代中。 #### 3. 永久代/元空间(Permanent Generation / Metaspace) 在Java 8之前,永久代是堆内存的一个特殊区域,用来保存类的元数据信息、常量池以及静态变量等。但从Java 8开始,永久代已经被移除,取而代之的是本地内存中的元空间(Metaspace)。这意味着类的元数据现在被存储在本地内存中,而不是JVM堆内存里,这有助于避免因加载大量类而导致的OutOfMemoryError问题[^1]。 ### 垃圾回收机制 针对堆内存的不同区域,JVM采用不同类型的垃圾收集器来进行有效的内存管理: - **Minor GC** 发生在新生代上,特别是Eden区满的时候触发。它会清理掉不再使用的对象,并将存活下来的对象移动到Survivor区或直接晋升到老年代。 - **Major GC 或 Full GC** 则发生在老年代上,处理那些长期存活的对象。Full GC会对整个堆进行一次全面的垃圾回收,包括新生代老年代,同时也可能涉及方法区(对于支持该概念的JVM实现)。 通过这样的结构设计,JVM能够有效地管理优化应用程序运行期间所需的内存资源,同时减少垃圾回收带来的性能影响。 ```java // 示例代码 - 展示如何设置JVM堆内存参数 public class HeapMemoryExample { public static void main(String[] args) { // 获取JVM堆内存相关信息 long initialMemory = Runtime.getRuntime().totalMemory(); long maxMemory = Runtime.getRuntime().maxMemory(); System.out.println("Initial heap size: " + initialMemory / (1024 * 1024) + " MB"); System.out.println("Max heap size: " + maxMemory / (1024 * 1024) + " MB"); } } ``` 使用上述示例程序可以帮助开发者了解当前JVM实例的堆内存配置情况。此外,还可以通过命令行选项来调整JVM启动时的堆内存大小,例如 `-Xms` 设置初始堆大小,`-Xmx` 设置最大堆大小等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值