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

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

1.从操作系统的角度

操作系统管理内存是作为开发者认识内存最基本的起点,对于windows 操作系统是通过对内存分页划分和管理的(Windows一个分页是4KB),这是为了让操作系统很快的寻址和管理。当然对于分页的寻址和回收也有自己各种各样的算法,每款系统都有自己的算法,这里就不多讲了(你可以在其他资料上面看到关于不同系统对于内存的管理,回收的原理和算法)。一般内存加载系统之后,系统占有的部分和应用占有分配的内存空间是独立分开的,除非应用调度系统的资源。

2.栈

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

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

一般在栈里面存储的数据是基本数据类型(int char double 等)和 指针句柄类型。

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

对于Android系统eclipse 我也没有看到设置栈的大小的资料,可能是不支持。Android系统对于2.0x版本分配给应用UI线程的栈大小是8kb,4.0x是16kb,注意这里是UI主线,包含视图句柄和其他的数据。其他的线程可能还要分配的栈空间,这些栈空间加在一起就是虚拟机对应用分配的栈空间,或者系统对虚拟机分配的栈空间(每个应用就是跑起来的虚拟机)。

3.堆

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

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

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

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

4.静态存储区

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

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

5.常量区

即常量的保存区域

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


还有一个概念--代码区

6.代码区

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

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

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

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


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

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

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

相关文章推荐

Java中Date及Timestamp时间相关内容(基本上看这一份就可以了)

Java中Date及Timestamp时间相关内容(基本上看这一份就可以了) java.util.date java.sql.date java.sql.timestamp 整理一: 这...

使用cobertura检测测试覆盖率

昨天写了一个很长方法的单元测试代码,然后BOSS检查了一下,找来自动化测试的哥们,帮着看了一下改进。那哥们建议我用cobertura测试一下代码覆盖率,听起来蛮有趣的,在他的帮助下做了一下。不算复杂,...

从JVM内存管理的角度谈谈静态方法和静态属性

作者     robbin   (http://hibernate.fankai.com/站长)           我试着从JVM的内存管理原理的角度来谈一下静态方法和静态属性的问题,不对的地方请指...

从JVM内存管理的角度谈谈JAVA类的静态方法和静态属性

在JVM中,内存分为两个部分,Stack(栈)和Heap(堆),这里,我们从JVM的内存管理原理的角度来认识Stack和Heap,并通过这些原理认清Java中静态方法和静态属性的问题。 一般,JVM...

从JVM内存管理的角度谈谈静态方法和静态属性

JVM的内存分为两部分:stack和heap:     stack(栈)是JVM的内存指令区。stack管理很简单,push一定长度字节的数据或者指令,stack指针压栈相应的字节位移;pop一定字节...
  • sbvfhp
  • sbvfhp
  • 2011年01月13日 18:10
  • 525

从JVM内存管理的角度谈谈静态方法和静态属性 和 java对象引用与JVM自动内存管理

试着从JVM的内存管理原理的角度来谈一下静态方法和静态属性的问题,不对的地方请指正。 (joezheng123.javaeye.com/blog/264695) JVM的内存分为两部分:stack和...

从JVM内存管理的角度谈谈静态方法和静态属性 和 java对象引用与JVM自动内存管理

试着从JVM的内存管理原理的角度来谈一下静态方法和静态属性的问题,不对的地方请指正。 (joezheng123.javaeye.com/blog/264695) JVM的内存分为两部分:stack和...

从JVM内存管理的角度谈谈静态方法和静态属性 和 java对象引用与JVM自动内存管理

试着从JVM的内存管理原理的角度来谈一下静态方法和静态属性的问题,不对的地方请指正。 (joezheng123.javaeye.com/blog/264695) JVM的内存分为两部分:stack和...

从开发者的角度学习Linux内存管理

在Linux开发的过程中对于内存的开发是有很多技巧可以掌握的。下文中就从开发者的角度去看如何进行Linux内核的管理。下文结合实例向大家介绍系统进程与内存之间的微妙关系。   内存管理一向是所有操...
  • uyiwfn
  • uyiwfn
  • 2012年06月01日 21:09
  • 373

从开发者的角度学习Linux内存管理

进程如何使用内存? 毫无疑问,所有进程(执行的程序)都必须占用一定数量的内存,它或是用来存放从磁盘载入的程序代码,或是存放取自用户输入的数据等等。不过进程对这些内存的管理方式因内存用途不一而不尽相同...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:从几个角度谈谈内存的管理和划分
举报原因:
原因补充:

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