从几个角度谈谈内存的管理和划分

原创 2016年08月29日 22:04:18

一.从操作系统的角度

操作系统管理内存是作为开发者认识内存最基本的起点,对于windows 操作系统与Linux系统是通过对内存分页或者分段划分和管理的(Windows一个分页是4KB),这是为了让操作系统很快的寻址和管理。当然对于分页的寻址和回收也有自己各种各样的算法,每款系统都有自己的算法,这里就不多讲了(你可以在其他资料上面看到关于不同系统对于内存的管理,回收的原理和算法)。对于内核级别而言,内存是按片管理,内核中也有执行的内核线程和方法栈;但是对于用户空间级别我们讨论代码和数据区才更加有意义。一般内存加载系统之后,系统占有的部分和应用占有分配的内存空间是独立分开的,除非应用调度系统的资源。

Linux和Windows系统对于其用户应用(用户空间)而言,主要有堆,栈,方法区和数据区。可参考《程序员的修养,连接加载与库》

二.从进程的角度

进程是直接从操作系统获取的内存空间,也是开发者角度的上内存管理划分。

1.栈

对于程序员而言,听到栈应该是很多的,但是是不是很是理解呢?

首先要知道栈是什么样的数据结构 -- 顺序结构,或者是存储序列,只是先压栈最后弹栈罢了。(堆是链表,不连续的)

一般在栈里面存储的数据是基本数据类型(int char double 等)和 指针句柄类型。一个栈结构对应的就是一个方法的指令!栈是对方法的指令的存储和指令管理。

栈一般不是程序员(开发者)控制的,它是编译器或者系统分配的,那么如果是编译环境控制的,我们认为能不能在编译环境设置或者编码设定呢?那么这要具体根据开发环境了或者说开发语言支不支持。对于 Windows一般分配的栈是2M。对于c#开发语言,我们可以在vs环境里面设置(#param comment clinker,"stack": 10000000   10M),但是对于c、c++语言我没有了解过是否支持设置。

对于Android系统每一个进程是一个虚拟机-dalvik,Android系统对于2.0x版本分配给应用UI线程的栈大小是8kb,4.0x是16kb,注意这里是UI主线,包含视图句柄和其他的数据。其他的线程可能还要分配的栈空间,这些栈空间加在一起就是虚拟机对应用分配的栈空间,或者系统对虚拟机分配的栈空间(每个应用就是跑起来的虚拟机)。

2.堆

它才是我们程序员天天打交道的东西,我们有权对其开发和回收。(尤其是面对对象编程,每一个对象几乎都是放在堆上面 "new 出来")

堆是链表结构,不是连续的。

在堆上面可以存储全局变量或者对象(对象包含自己的成员变量和方法)

当然不同的系统 对堆的限制也不一样,对于Android系统而言貌似是限制在256M,对于Windows系统貌似只要你的内存够大,你可以随意的开发。

3.数据区(包含静态变量,常量,全局变量)

静态存储

static声明的变量或者方法或者常量

和系统没有什么关系,系统不关心什么static,只是编译器关心的,要么自己搞一个static区域或者直接在堆中保存。因为有的语言在编译的过程中,直接将static存储在堆,没有所谓的static区域,只是其生命周期是伴随整个应用。

常量

即常量的保存区域

和系统没有什么关系,系统不关心什么常量,只是编译器关心的,要么自己搞一个常量区域或者直接在堆中保存。因为有的语言在编译的过程中,直接将常量存储在堆。


还有一个概念--代码区

4.代码区

也许很人也听说这个名词,其实这个概念就不涉及什么内存的划分,这个概念应该是操作系统的东西。

我们知道开启一个应用,对于系统而言就是创建一个进程,(进程里面可能包含一个或者在多个线程,那就看你的应用是多线程的还是多线程的)进程是由三部分组成:sp,pcb和代码区。pcb是程序控制模块,sp是指令计数器,代码区就是这个应用要执行的指令和数据,换句话说就是你具体要干的什么事。代码区的数据和指令就是要在栈和堆里面创建的数据和执行的指令。

如果你开好几个应用,并行执行,比如你在听歌又在敲代码,那么属于不同进程的多线程,CPU在不同的时间片上切换不同的线程(时间片20ms).

注意:同一进程的多线程之间可以共享数据,但是不同进程中的线程不能共享数据


上面所说的似乎阅读起来是从系统方面和编译器方面对内存管理做了角度叙述,但是说回来,编译环境对内存进行划分还是基于系统的,所以本质上还是系统对内存进行的划分。之所以上面这样划分形式的阐述是为了加强一个应用从诞生的角度(编码)理解内存和相关数据的生命周期。

系统起一个进程,分配了内存空间,进而也会更细化的对线程数据和指令存储进行划分,这进一步的划分是根据生命周期和作用域。


版权声明:本文为博主原创文章,未经博主允许不得转载。

java对象内存管理的简单认识!

java里面有句名言:Everything is object!但是java还算不上是纯面向对象的语言。它的数据类型包括基本数据类型(byte,short,int,char,long ,float,d...
  • superxiaolong123
  • superxiaolong123
  • 2017年03月22日 20:36
  • 180

java堆内存的划分

根据对象的存活率(年龄),Java对内存划分为3种:新生代、老年代、永久代1、新生代: 比如我们在方法中去new一个对象,那这方法调用完毕后,对象就会被回收,这就是一个典型的新生代对象。 现在的商业...
  • liudezhicsdn
  • liudezhicsdn
  • 2016年04月04日 17:57
  • 1093

以前端角度出发做好SEO需要考虑什么

网站的速度是很多人都面临的问题,其实许多网站,都没有特意的去优化加载速度,对于一个网站来说,加速不但提高了用户体验(如果一个网站在几秒内没 有打开,大多数用户选择的是关闭而非等待),而且对于SEO的流...
  • ayangjing
  • ayangjing
  • 2013年10月24日 13:33
  • 1900

JVM的内存区域划分

由于Java程序是交由JVM执行的,所以我们在谈Java内存区域划分的时候事实上是指JVM内存区域划分。在讨论JVM内存区域划分之前,先来看一下Java程序具体执行的过程:    如上图所示,...
  • mu_jiao
  • mu_jiao
  • 2015年05月28日 20:10
  • 4221

Java内存区域划分、内存分配原理

总结自《深入理解Java虚拟机》之内存区域划分。
  • OyangYujun
  • OyangYujun
  • 2014年11月16日 16:20
  • 25005

简单谈谈我对JVM内存管理的理解(1)

虚拟机是
  • liushuilining
  • liushuilining
  • 2014年09月07日 19:27
  • 1134

Linux内核中的内存管理浅谈 .

http://blog.csdn.net/jasonblog/article/details/4848977原文链接   1。基本框架(此处主要谈页式内存管理) 4G是一个比较敏感的字眼,早些日...
  • acs713
  • acs713
  • 2013年02月07日 12:04
  • 2949

Redis中的内存管理:关于zmalloc

Redis是一种使用C语言编写的NoSQL数据库,特点是高性能,高灵活性。但由于C语言没有自带GC,所以Redis在实际使用过程中,内存的分配和释放的合理性和高效性就非常重要。为了达到这个目的,Red...
  • caishenfans
  • caishenfans
  • 2015年03月24日 20:37
  • 2303

谈谈创业或者参加创业团队的成败与心得

欢迎使用Markdown编辑器写博客本Markdown编辑器使用StackEdit修改而来,用它写博客,将会带来全新的体验哦: Markdown和扩展Markdown简洁的语法 代码块高亮 图片链接和...
  • bingdongguke
  • bingdongguke
  • 2015年04月18日 00:52
  • 1395

从用户角度的软件设计

如果我们使用浏览器可以进行服务端业务逻辑和客户端界面逻辑所有的编程,类似于一个比较著名的技术SharePoint,但是它还是必需要开发人员进行二次的定制开发,从开发工具的角度去理解,它是一个史上来讲最...
  • luckeast
  • luckeast
  • 2017年03月23日 11:42
  • 340
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:从几个角度谈谈内存的管理和划分
举报原因:
原因补充:

(最多只允许输入30个字)