网站首页 > java教程 正文
写作的意义在于分享,在于遇见。
昨天发文后,我收到了一条评论,问我不知道什么是堆内存和栈内存。 因此,才有了今天这篇文章。
数据结构里的栈和堆
如果学过数据结构这门课,一定对“栈”和“堆”这两个词不陌生。
栈表示一种先进后出(LIFO,last in first out,后进先出)的数据结构。类比生活中,就像是训练有素的服务员堆脏盘子,理应按照从下面开始堆上去的反方向,也就是从上往下开始洗盘子。这里的堆盘子和洗盘子,就是数据的存和取。
堆在数据结构里,是一种特殊的树结构:一般有最大堆和最小堆。如下图。最小堆根结点都不大于左右孩子。最大堆的根结点都不小于左右孩子。
除了表示一种数据结构,还可以表示内存分配的通用空间。而堆内存,则指的就是后者的含义。
Java 为什么会有两种内存分配方式呢?
栈来存数据时,你只能取出你最后加进去的。这种方式对局部变量来说就刚刚好。因为他们会随着函数的调用,就来了,函数结束,就要消失。栈让追踪变得很简单,因为最后保存的一定是最先被释放的。
但是栈并不适合一些随意的数据,这些数据的生命周期并不遵循单独的函数那样。这时,堆内存就可以允许你任意去添加或删除这些数据。
所以栈在内存中占的空间,比 Java 堆空间少太多了。因为方法一结束,在这个方法里创建的所有变量都会被永久清除掉。
Java 中的栈内存用于静态内存分配和线程的执行。如果栈内存满了,会抛出异常:java.lang.StackOverFlowError 。而且是线程安全的,因为线程之间是被隔离开来的。
Java 中的堆内存为 Java 对象和 JRE 类动态分配内存。如果堆内存满了,抛出的异常是: java.lang.OutOfMemoryError。
栈内存和堆内存的不同主要体现在以下几点:
- 程序应用上:栈内存是在执行栈帧的时候,被方法所使用,堆内存是被整个应用在所有运行时间使用。
- 存储的东西:栈内存只存主要变量和堆中创建的对象的引用,堆内存存所有被创建的对象。
- 使用顺序:栈内存就是用 LIFO 的顺序管理的,堆内存则是通过复杂的内存管理技术来存取的(之前文章提过的年轻代、年老代和永久代)。
- 效率上:栈内存要比堆内存快。
- 分配和回收:方法被调用的时候,栈内存就被开辟了,方法返回时,就被回收;
当新对象被创建的时候,堆内存被开辟,如果没有任何引用了,就会被垃圾回收器回收掉。
参考链接:
https://stackoverflow.com/questions/2787611/why-does-java-uses-heap-for-memory-allocation
https://www.geeksforgeeks.org/heap-data-structure/
猜你喜欢
- 2024-11-12 本地方法栈、JVM栈、本地内存和JVM Heap的区别与关系
- 2024-11-12 Java基础之堆、栈、方法区、类加载器——JVM内存模型分析
- 2024-11-12 java之栈内存与堆内存(栈内存 和堆内存)
- 2024-11-12 深入了解Java虚拟机栈以及内存模型
- 2024-11-12 Java虚拟机栈区域(虚拟机栈描述的是java方法执行的内存模型)
- 2024-11-12 一文读懂Java的“栈内存”[Stack]和“堆空间”[Heap]
- 2024-11-12 JVM 内存结构(jvm内存结构及作用)
- 2024-11-12 「JVM系列」 从一到掌握JVM系列之Java虚拟机栈
- 2024-11-12 Java中堆和栈的区别(java中堆和栈的区别在哪)
- 2024-11-12 一文读懂Java本地方法栈(本地方法栈jni)
你 发表评论:
欢迎- 06-15Linux中如何通过Shell脚本来控制Spring Boot的Jar包启停服务?
- 06-15推荐一款超棒的SpringCloud 脚手架项目
- 06-15IDEA将项目打包成jar包(idea打包普通java项目)
- 06-15Spring Boot3 项目 jar 包打包成 Docker 镜像全攻略
- 06-15记录Dockerfile将jar包构建成部署所需的镜像
- 06-15项目基础部署汇总八---linux下xxl-job安装
- 06-15Spring Boot Jar 包秒变 Docker 镜像实现多环境部署
- 06-15终端执行 java -jar example.jar 时报错:“没有主清单属性” 的解决
- 最近发表
-
- Linux中如何通过Shell脚本来控制Spring Boot的Jar包启停服务?
- 推荐一款超棒的SpringCloud 脚手架项目
- IDEA将项目打包成jar包(idea打包普通java项目)
- Spring Boot3 项目 jar 包打包成 Docker 镜像全攻略
- 记录Dockerfile将jar包构建成部署所需的镜像
- 项目基础部署汇总八---linux下xxl-job安装
- Spring Boot Jar 包秒变 Docker 镜像实现多环境部署
- 终端执行 java -jar example.jar 时报错:“没有主清单属性” 的解决
- 如何将本地JAR文件添加到Maven项目中
- Java 类隔离应用:多 Jar 包支持(java接口隔离原则)
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)