堆内存与栈内存
Java把内存划分成两种:一种是栈内存,一种是堆内存。
一、栈内存 (栈:仓库旅馆等,有规则、有顺序的结构)
存放基本类型的变量(int, short, long, byte, float, double, boolean, char)和对象句柄(对象的引用)。对象的引用和方法调用,遵循先入后出的规则。
在方法中定义的“一些基本类型的变量和对象的引用变量”都在方法的栈内存中分配。当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。
Java中的代码是在方法体中执行的,每个方法主体都会被放在栈内存中,比如main方法。假如main方法里调用了其他的方法,比如add(),那么在栈里面的存储就是最底层是main,mian上面是add。栈的运行时后入先出的,所以会执行时会先销毁add,再销毁main。
栈的优势是:存取速度比堆要快,仅次于寄存器。栈中的数据可以共享,但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。
二、堆内存
存放所有new出来的对象。(特此强调,堆内存和数据结构中的堆完全是两码事,分配方式倒是类似于链表。)
堆内存是区别于栈区、全局数据区和代码区的另一个内存区域。堆允许程序在运行时动态地申请某个大小的内存空间,堆内存实际上指的就是(满足堆内存性质的)优先队列的一种数据结构,第1个元素有最高的优先权。
另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。堆内存是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆内存的大小受限于计算机系统中有效的虚拟内存。由此可见,堆内存获得的空间比较灵活,也比较大。堆内存是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便。
三、其他数据存储
1、常量池:存放基本类型常量和字符串常量(public static final)
2、静态域:存放静态成员(static定义的)
3、非RAM存储:硬盘等永久存储空间
堆和栈的区别可以用如下的比喻来看出:
使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。
使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是符合自己的口味,自由度更大。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 2 本地部署DeepSeek模型构建本地知识库+联网搜索详细步骤