关于堆(Stack)和栈(Heap)

堆和栈的概念,在数据结构、C/C++、Java中,是完全不同的。必须明确讨论的范围,才能给出具体的答案。

以下内容整理自《大话数据结构》及网友博客

数据结构中的堆和栈

堆的来源

简单选择排序中,并没有做到把每次比较的结果保存下来,因此存在一定的浪费。

1964年,Floyd和Williams共同发明了堆排序(Heap Sort)算法。该算法是对简单选择排序的一种改进。通过堆排序,可以避免浪费每次比较的结果,并最终得到“堆”这一数据结构。

堆的特点

一棵完全二叉树(complete binary tree),且所有节点都大于或等于其孩子。

补充一下完全二叉树的定义:所有的节点,按照从上到下、从左往右的顺序,没有空档。

在堆排序的过程中,要实时进行数组建堆(Heapify)的操作,使数据满足堆的定义。

具体操作,可以查看B站up主“正月点灯笼”的视频:
堆排序(heapsort)

栈的定义

栈,是限定仅在表尾进行插入和删除操作的线性表。

允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不含任何数据元素的栈称为空栈。栈又称为先进后出(Last In First Out)的线性表,简称LIFO结构。

进出栈的变化形式

最先进栈的元素,是不是只能最后出栈呢?

不一定。

在进栈过程中插入出栈步骤,即可改变其出栈顺序。
例如,现在有 0,1,2三个元素依次进栈。出栈顺序为1,0,2。怎样做到呢?

0进,1进,1出,0出,2进,2出。

栈的用途

  1. 递归
  2. 四则运算表达式求值(带括号)

C/C++中的堆和栈

(此处较为简略)

一般由程序员分配释放,若程序员不释放,则可能会引起内存泄漏。
注:堆和数据结构中的堆栈不一样,其本质是链表。

由编译器自动分配释放,存放函数的参数值,局部变量等值。其操作方式类似于数据结构中的栈。大小固定,若存入数据量达到上限,则会发生爆栈。

<!--

hold on...

-->

Java中的堆和栈

Java中的堆和栈的概念,存在于JVM(Java虚拟机)中。

既然说到JVM——
在这里插入图片描述
这个图一定要做到深入理解,在面试时可以手画出来,并且理解其中的每一个步骤。

具体可参见博文(上图来源)
深入理解Java虚拟机-Java内存区域与内存溢出异常

  • 线程:公有
  • 生命周期:虚拟机启动时创建

对于大多数应用而言,堆是JVM所管理的内存中最大的一块。是被所有线程共享的一块区域。在虚拟机启动时创建。此内存区域的唯一作用就是存放对象实例。几乎所有的对象实例都是在这里分配的(不绝对,在虚拟机的优化策略下,也会存在栈上分配、标量替换的情况)。

Java堆是GC回收的主要区域,因此也被叫做GC堆。
从这一角度看,堆又被划分为如下的区域:

新生代(Young Generation)老年代(Old Generation)
Eden
From Survivor & To Survivor

新的对象分配是首先放在年轻代 (Young Generation) 的Eden区,Survivor区作为Eden区和Old区的缓冲,在Survivor区的对象经历若干次收集仍然存活的,就会被转移到老年代Old中。

具体过程可参见B站UP主“程序员诸葛”的视频,其中P6详细讲解了JVM的垃圾回收机制:
2020年最新Java虚拟机JVM底层原理分析视频教程全集

在面试时,可以详细展开GC算法。

JVM中有两个“栈”,分别是“Java虚拟机栈”和“本地方法栈”。

Java虚拟机栈

  • 线程:私有
  • 生命周期:和线程相同

线程执行期间,每个方法被执行时,都会创建一个栈帧(Stack Frame)用于存储以下内容:

局部变量表
操作(数)栈
动态链接
方法出口(返回地址)

这四种组成元素的具体结构和功能,可参见上述博文链接或B站视频P2、P3。

每个方法从被调用到执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

本地方法栈

  • 线程:私有
  • 生命周期:和线程相同

本地方法栈和Java虚拟机栈发挥的功能非常类似。主要区别是:

Java虚拟机栈:执行Java方法服务;
本地方法栈:执行Native方法服务(通常用C编写)。

有些虚拟机发行版本(譬如SunHotSpot虚拟机)直接将本地方法栈和Java虚拟机栈合二为一。与虚拟机栈一样,本地方法栈也会抛出StackOverflowError和OutOfMemoryError异常。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值