MyException - 我的异常网
当前位置:我的异常网» 数据结构与算法 » 学习笔记:内存储器,堆栈,到底为何物

学习笔记:内存储器,堆栈,到底为何物

www.MyException.Cn  网友分享于:2015-02-03  浏览:0次
学习笔记:内存,堆栈,到底为何物?
     在网上看到了一篇关于面试的博客文,突然发现自己对于这个博主而言简直差的是十万八千里,他提到的许多技术我尽然一个也答不上来。于是就开始反思,还是要抱一抱佛脚。左看右看发现了内存这个面试的万恶之源。
 
     说实话对于内存这种东西即使是一点也不了解的人也能写出许多的程序,但有一个现实问题就是面试时总是会用这些基础知识来考面试的人。我曾经出面试题的时候也做过一样的事情,但是想想自己其实也不懂。最近开始更新自己的简历,期望来年能找到一份新的工作,才想起自己还是那个什么都不懂的开发人员,还是要面对面试官的考问。
 
话说什么是内存?
内存是计算机中重要的部件之一,它是与CPU进行沟通的桥梁。计算机中所有程序的运行都是在内存中进行的,因此内存的性能对计算机的影响非常大。内存(Memory)也被称为内存储器,其作用是用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器交换的数据。只要计算机在运行中,CPU就会把需要运算的数据调到内存中进行运算,当运算完成后CPU再将结果传送出来,内存的运行也决定了计算机的稳定运行。 内存是由内存芯片、电路板、金手指等部分组成的。

——摘自百度百科

 
看完后简单无法直视,这和我想了解的东西有什么关系呢?
我的理解为:内存是一种存储器,硬件上来说就是一种可以快速存储计算机数据,CPU将这些数据取得运算。内存就像一个大数组,可以存放许多数据。
 
     这里就有一个很重要的问题,CPU和内存储器都是硬件,谁来负责操作这些硬件呢?这就要说到操作系统了。我们通常用的windows、linux、unix这些操作系统,那么就很自然的想到了对于内存操作与管理其实还是由操作系统提供了机制,应用程序在这个基础上再完成相应的内存操作。
 
网上找了找资料,windows和linux的内存管理机制来看,都将内存划分为了物理内存和虚拟内存。
  • 物理内存
    物理内存就是系统硬件提供的内存大小,是真正的内存,说土点就是那内存条
 
  • 虚拟内存
    虚拟内存就是为了满足物理内存的不足而提出的策略,它是利用磁盘空间虚拟出的一块逻辑内存,用作虚拟内存的磁盘空间被称为交换空间(Swap Space)。然后对于内存的操作需要有一种访问的方法,既然内存是CPU的暂时存数据的地方,那么CPU读取数据时肯定要有方法去读取吧,这就是要说到-内存地址。
 
考虑到内存资源总是有限的,而对于多任务的操作系统来说,应用程序越多自然占用的就越多,那如何合理的分配内存资源呢?有两种划分方法:分段、分页。
 
到这我倒是有了一些简单的理解:
所有的应用程序都是通过编绎器编绎为了可执行文件,在这个文件里会有许多的描述内容和程序指令。当这个应用启动时,操作系统会创建一个进程,并在这个进程中分配一个地址空间,而后随着应用的不断执行和操作系统与CPU的调度会不断的在虚拟地址和物理地址之间做映射,从而拥有了真实的内存空间,可以输入指令和数据供CPU执行。
 
再来看看堆栈
堆栈这个名词不陌生,但对于许多开发人和我一样只知其名,不知其实。写这个笔记原因是因为我没有理解内存与堆栈为什么总会放在一起讨论?于是边看资料边记录笔记。
 
在计算机领域,堆栈是一个不容忽视的概念,堆栈是两种数据结构。堆栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除。在单片机应用中,堆栈是个特殊的存储区,主要功能是暂时存放数据和地址,通常用来保护断点和现场。要点:堆,列队优先,先进先出[1] 。栈,先进后出(First-In/Last-Out)。——摘自百度百科
 
看到这个概念我最大的疑问是,堆栈是两种数据结构?这就是典型的数据结构没学好的人的反应,呵呵。没办法只能继续寻找资料学习。于是在学习过程中慢慢的就有些理解。
 
先看看堆栈的一些定义和说明
栈(数据结构):一种先进后出的数据结构。——摘自百度百科

 

    这句话让我想到一个问题,那就是先进后出的这种数据结构有什么作用呢?带着这个疑问就去寻找栈的应用场景,下面这个场景突然让我些明白了什么:
    “栈可以用来在函数调用的时候存储断点,做递归时要用到栈!”
    对呀,当我们的代码在运行的时候不就可以看到一个“栈”嘛,先把方法压栈,然后逐个的取出来执行。这样代码的效率就高了许多,而且顺序不会出错。
    好了,有了这个理解再看下面的内容:
 
栈(操作系统):由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
 
栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,栈数据可以共享,详见第3点。堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,但缺点是,由于要在运行时动态分配内存,存取速度较慢。——摘自百度百科
这里就说明了栈的优点和缺点,同时也引出了栈与堆的区别。所以可以理解栈这种数据结构就是用于大小和周期明确的高速存取结构。
一般存在栈中的数据都有哪些?比如值类型(特别是基本数据类型)和对象句柄之类。
看了栈对于堆的理解就要好多了,先看看定义:
  • 堆(操作系统): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。
  • 堆(数据结构):堆可以被看成是一棵树,如:堆排序。
     ——摘自百度百科

 

堆(英语:heap),是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵树的数组对象。在队列中,调度程序反复提取队列中第一个作业并运行,因为实际情况中某些时间较短的任务将等待很长时间才能结束,或者某些不短小,但具有重要性的作业,同样应当具有优先权。堆即为解决此类问题设计的一种数据结构。
    ——摘自维基百科
 
所以堆要灵活的多,分配与释放都可以按需进行。在栈中也说过堆的优点是灵活,缺点也是因为灵活存取效率会低一些。
其实就数据结构来说,堆就是一个数组或者链表,可以看作是一颗完全二叉树的存储结构,他的特点就是先进先出。
 
总结
有了对内存和堆栈的一些基本概念后,再回头看一下自己的问题,内存和堆栈到底为何物?
 
我的理解内存是计算机的一个硬件组成部分,是CPU执行指令的数据存储区,内存就是提供了这一块存储空间。想要使用这块存储空间就得用到操作系统,由于与硬件打交道的就是操作系统,而操作系统决定了对内存的管理机制。而应用软件需要对内存进行存取就要用到堆栈,这是两种数据结构,决定了数据在内存空间里的存储结构。
 
应用程序在内存中的存储结构是由编绎器决定的。这个我的描述可能不准确,下面说一下C++中内存的分区机制可能会比较好理解一些。 
  • ,就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参数等。 
  • ,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。 
  • 自由存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。 
  • 全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。 
  • 常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改(当然,你要通过非正当手段也可以修改,而且方法很多)
 
 
写到这感觉还是有许多的疑问,为什么内存的管理会使用这些数据结构呢?堆栈之外有没有更好的办法来管理?这是否与计算机的发展历史有关呢?
3楼代码小兵的成长
受不了,咋都是百度百科,我看了一半不想看了,楼主你重新更改一下资料来源吧
Re: 5207
@代码小兵的成长,引用受不了,咋都是百度百科,我看了一半不想看了,楼主你重新更改一下资料来源吧,呵呵,我是边看边学的,所以就实际看了什么资料就写什么。。主要内容还是我自己的一些疑问和思考,对于这个定义也就没太在意来源。
Re: 5207
@代码小兵的成长,如果有什么资料也希望能介绍一下,供我学习一下。。
2楼115889198
大家可以加QQ群java技术交流群 232267681 ,,在此等候大家,为新人不知道如何学习java排忧解难111
1楼代码小兵的成长
堆栈是两种数据结构,我也笑了

文章评论

每天工作4小时的程序员
每天工作4小时的程序员
 程序员的样子
程序员的样子
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
我的丈夫是个程序员
我的丈夫是个程序员
为什么程序员都是夜猫子
为什么程序员都是夜猫子
程序员和编码员之间的区别
程序员和编码员之间的区别
程序员应该关注的一些事儿
程序员应该关注的一些事儿
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
如何成为一名黑客
如何成为一名黑客
那些争议最大的编程观点
那些争议最大的编程观点
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
旅行,写作,编程
旅行,写作,编程
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
10个调试和排错的小建议
10个调试和排错的小建议
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
总结2014中国互联网十大段子
总结2014中国互联网十大段子
编程语言是女人
编程语言是女人
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
程序员必看的十大电影
程序员必看的十大电影
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
鲜为人知的编程真相
鲜为人知的编程真相
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
一个程序员的时间管理
一个程序员的时间管理
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
中美印日四国程序员比较
中美印日四国程序员比较
我是如何打败拖延症的
我是如何打败拖延症的
漫画:程序员的工作
漫画:程序员的工作
Java程序员必看电影
Java程序员必看电影
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
代码女神横空出世
代码女神横空出世
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有