jvm的栈和堆

在 JVM 中,栈(Stack)和堆(Heap)是两种核心内存区域,用于存储不同类型的数据,它们的设计和存储规则有明确区分,主要体现在存储内容、生命周期和管理方式上:

一、栈(Stack,线程私有)

栈是线程独占 的内存区域,每个线程创建时都会分配一个栈,用于存储线程执行过程中的局部变量、方法调用信息等,遵循 "先进后出"(FILO)的原则。

存储内容:

  1. 局部变量 :方法内定义的基本数据类型(intcharboolean 等)和对象引用(指向堆中对象的地址,而非对象本身)。

    例如:int a = 10; String s = new String("abc"); 中,a 的值(10)和 s 的引用(地址)存储在栈中,而 "abc" 对象本身在堆中。

  2. 方法调用信息(栈帧):每个方法被调用时,JVM 会在栈中创建一个 "栈帧",包含:

    • 方法的参数
    • 局部变量表
    • 操作数栈(临时计算空间)
    • 方法返回地址(调用该方法的位置)

方法执行完毕后,栈帧会被自动弹出并释放内存,无需 GC 参与。

特点:

  • 生命周期与线程绑定:线程结束,栈内存自动释放。
  • 大小固定 :栈的内存空间在 JVM 启动时可通过参数(-Xss)设置,超出会抛出 StackOverflowError(如递归调用过深)。
  • 访问速度快:栈是连续的内存空间,由 JVM 直接管理,读写效率高于堆。

二、堆(Heap,线程共享)

堆是 JVM 中最大的内存区域,被所有线程共享 ,用于存储对象实例和数组,是垃圾回收(GC)的主要区域。

存储内容:

  1. 对象实例 :通过 new 关键字创建的对象(包括所有成员变量,无论基本类型还是引用类型)。

    例如:User user = new User(); 中,User 类的实例(包含其成员变量,如 nameage)存储在堆中,user 是指向该对象的引用(存在栈中)。

  2. 数组 :所有数组(无论基本类型数组还是对象数组)的元素都存储在堆中。

    例如:int[] arr = new int[10]; 中,数组的 10 个 int 元素存储在堆中,arr 是引用(存在栈中)。

特点:

  • 动态分配内存 :堆的大小可动态调整(通过 -Xms 初始大小、-Xmx 最大大小设置),没有固定的生命周期。
  • 垃圾回收管理:堆中对象不再被引用时,不会立即释放内存,而是等待 GC 定期回收,这也是 Java 自动内存管理的核心。
  • 内存碎片化可能:由于对象频繁创建和回收,堆可能产生内存碎片(通过 GC 算法优化,如标记 - 整理可减少碎片)。

三、核心区别总结

维度 栈(Stack) 堆(Heap)
所有者 线程私有(每个线程一个栈) 所有线程共享
存储内容 局部变量、方法栈帧、对象引用 对象实例、数组
生命周期 随方法调用 / 线程结束而创建 / 销毁 随对象是否被引用动态变化(由 GC 管理)
内存管理 自动弹出栈帧,无需 GC 依赖 GC 回收无引用对象
访问速度 快(连续内存,直接操作) 较慢(需通过引用定位,可能有碎片)
异常类型 栈溢出(StackOverflowError 内存溢出(OutOfMemoryError

一句话概括

栈存局部变量和方法调用信息,随线程 / 方法生命周期自动管理;堆存对象实例和数组,由 GC 动态回收。这种分离设计既保证了局部数据的高效访问,又实现了对象内存的灵活管理,是 JVM 内存模型的核心基础。

相关推荐
金銀銅鐵3 小时前
[java] 编译之后的记录类(Record Classes)长什么样子(上)
java·jvm·后端
m0_495496413 小时前
mysql处理复杂SQL性能_InnoDB优化器与MyISAM差异
jvm·数据库·python
forEverPlume4 小时前
PHP怎么使用Eloquent Attribute Composition属性组合_Laravel通过组合构建复杂属性【方法】
jvm·数据库·python
2301_809204704 小时前
mysql在docker容器中如何部署_利用docker-compose快速启动
jvm·数据库·python
2301_815901978 小时前
SQL如何将多行记录聚合成逗号分隔字符串_GROUP_CONCAT技巧
jvm·数据库·python
zjy277779 小时前
Layui tab选项卡如何动态根据ID值进行程序化切换
jvm·数据库·python
m0_602857769 小时前
Redis如何修复槽位分配重叠的脏状态_使用redis-cli --cluster fix工具扫描并修复不一致的Slot
jvm·数据库·python
2301_766283449 小时前
怎样开启phpMyAdmin的操作审计日志_记录每条执行的SQL
jvm·数据库·python
zhoutongsheng10 小时前
如何解决ORA-01078参数文件错误_pfile与spfile互相创建恢复
jvm·数据库·python
2401_8242226910 小时前
HTML怎么标注字数限制提示_HTML实时字数统计占位【详解】
jvm·数据库·python