一、前菜:数据结构中的堆栈
用两个图,一看就能明白:
栈 堆堆是一种常用的树形结构,是一种特殊的完全二叉树,当且仅当满足所有节点的值总是不大于或不小于其父节点的值的完全二叉树被称之为堆。堆的这一特性称之为堆序性。因此,在一个堆中,根节点是最大(或最小)节点。如果根节点最小,称之为小顶堆(或小根堆),如果根节点最大,称之为大顶堆(或大根堆)。堆的左右孩子没有大小的顺序。
问:现在我有一个十万大小的数据集,要从中寻找选出最大的10个元素,怎么做呢?
答:用堆。分治递归。
树,二叉树(从左到右垂直有序),平衡二叉树(左右高度限制),b树,b+树,完全二叉树,堆(上下每一层大小是有序的,左右大小无序),大根堆,小根堆。
b树:mysql的索引数据结构。
然而,数据结构中的堆栈和编程里的内存堆栈似乎是两码事。
二、堆内存和栈内存
栈:为编译器自动分配和释放,如函数参数、局部变量、临时变量等等;
堆:为成员分配和释放,由程序员自己申请、自己释放。否则发生内存泄露。典型为C使用new申请的堆内容;
静态存储区:内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。它主要存放静态数据、全局数据和常量。
一般是系统自动回收堆空间。 像JAVA这种常驻内存或者C 中的malloc和new申请堆内存,需要手动回收机制的语言需要特别注意内存的手动释放,如果占用太多不释放很容易内存泄漏。
对于堆来讲,生长方向是向上的,也就是向着内存地址增加的方向;对于栈来讲,它的生长方向是向下的,是向着内存地址减小的方向增长。
例子说明:
1、如果你用new来生成的对象都是放在堆中的,而直接定义的局部变量都是放在栈中的,全局和静态的对象是放在数据段的静态存储区。
例如: Class People;People p;//栈上分配内存
People* pPeople;pPeople = new People;//堆上分配内存
2、PHP中对象名称存在栈内存。
p1=new Person();
对于这个条代码,$p1是对象名称在栈内存里面new Person()是真正的对象是在堆内存里面的。每new一次开辟一个堆空间。
3、C中:
因为常驻内存不释放,又一直在累加导致coredumpswoole中尽量少用全局变量:
本来静态变量是为了调用方便,不用实例化,提升效率,节省空间。但是如果执行完内存不释放,而且每次运行数据都在不断叠加的,如图1,要等work进程退出后才释放,不断占用内存空间导致泄露。反而得不偿失!!!
网友评论