C++、java都将线程共享的变量等放到堆内存中,为什么选择堆这种数据结构?
一、C++、java为什么选择堆这种数据结构
效率:执行堆排序所需的时间呈对数增长,而其他算法可能随着要排序的元素数量的增加而呈指数级增长。这种排序算法非常有效。
内存使用: 内存使用是最小的,因为除了保存要排序的元素的初始列表所必需的东西之外,它不需要额外的内存空间来工作
简单性: 它比其他同样有效的排序算法更容易理解,因为它不使用先进的计算机科学概念,如递归。
堆排序(HeapSort)基本概念
堆排序是一种基于二叉堆(binary heap)数据结构的基于比较的排序技术。它类似于选择排序,先找到最小的元素,然后把最小的元素放在最开始, 然后对其余元素重复相同的过程。
堆的介绍详见数据结构–Heap介绍及Java代码的实现示例
由于二叉堆是一棵完整的二叉树,所以它可以很容易地表示为数组,而基于数组的表示方式非常节省空间。如果父节点存储在索引I,左边的子节点可以用2 * I + 1计算,右边的子节点可以用2 * I + 2计算(假设索引从0开始)。
堆排序是一种in-place算法,排序后,相同的元素无法保证相对的顺序,即是不稳定的。
延伸阅读:
二、堆和栈的不同
1、分配方式不同:
栈: 由系统自动分配。 例如,声明在函数中一个局部变量 int b; 系统自动在栈中为b开辟空间
堆: 需要程序员自己申请,并指明大小,在c中malloc函数
如p1 = (char *)malloc(10);
在C++中用new运算符
如p2 = (char *)new(10);
但是注意p1、p2本身是在栈中的。
2、空间大小不同:
一般来讲在32位系统下,堆内存可以达到4G的空间,从这个角度来看堆内存几乎是没有什么限制的。但是对于栈来讲,一般都是有一定的空间大小的,例如,在VC6下面,默认的栈空间大小是1M。
3、分配效率不同:
栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执 行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考 数据结构/操作系统)在堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可能调用系统功能去增加程序数据段的 内存空间,这样就有机会分到足够大小的内存,然后进行返回。显然,堆的效率比栈要低得多。
4、碎片问题:
栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,
会遍历该链表,寻找名列前茅个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块 内存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的 大小,系统会自动的将多余的那部分重新放入空闲链表中。
对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块从栈中间弹出,在他弹出之前,在他上面的后进的栈内容已经被弹出。
5、生长方向:
对于堆来讲,生长方向是向上的,也就是向着内存地址增加的方向;对于栈来讲,它的生长方向是向下的,是向着内存地址减小的方向增长。
堆和栈相比,由于大量new/delete的使用,容易造成大量的内存碎片;由于没有专门的系统支持,效率很低;由于可能引发用户态和核心态的切换,内存的申请,代价变得更加昂贵。所以栈在程序中是应用较广泛的,就算是函数的调用也利用栈去完成,函数调用过程中的参数,返回地址,EBP和局部变量都采用栈的方式存放。所以,我们推荐大家尽量用栈,而不是用堆。虽然栈有如此众多的好处,但是由于和堆相比不是那么灵活,有时候分配大量的内存空间,还是用堆好一些。

猜你喜欢LIKE
相关推荐HOT
更多>>
如何进行安卓应用上传?
一、注册开发者账号在进行安卓应用上传之前,首先需要注册一个开发者账号。目前,Google Play Store是最大的安卓应用市场,因此注册一个Google ...详情>>
2023-10-16 10:55:22
前端html5框架有哪些?
一、BootstrapBootstrap是目前较受欢迎的前端HTML5框架之一。它由Twitter开发并开源,提供了一套易于使用的CSS和JavaScript组件,可以用于创建...详情>>
2023-10-16 10:42:42
怎么利用UIBE的数据库计算GVC指数?
一、怎么利用UIBE的数据库计算GVC指数UIBEGVC数据库里的第二个关于增加值%的计算放在了一个三维表里,对数据指标的使用有一个word文件。名列前...详情>>
2023-10-16 10:18:21
MySQL数据库全量、增量备份与恢复怎么做?
一、MySQL数据库全量备份与恢复步骤1、创建专用备份文件夹mkdir -p /data/backup2、执行全量备份命令/usr/bin/mysqldump -uroot -padmin --loc详情>>
2023-10-16 09:45:00热门推荐
MySQL的主从切换在什么情况下使用?
沸如何进行安卓应用上传?
热前端html5框架有哪些?
热Oracle迁移MySQL需要考虑什么?
新怎么利用UIBE的数据库计算GVC指数?
积分制管理与传统管理方法有什么不同?
插入数据前必须使用USE选择操作的数据库吗?
MySQL数据库全量、增量备份与恢复怎么做?
MySQL怎么保证数据库表中的数据根据系统时间实时更新?
Oracle数据库中生产库、查询库、测试库有什么区别?
写好的java可执行程序在其他电脑上如何使用?
数据库中的索引条目(index entry)是什么?
mysql字符串内部是怎么比较大小的?
数据仓库中,什么是business key?
技术干货






