一、当你运行你的程序通常都会访问哪些内存空间呢?

电脑自言自语道,“这个人要声明一个整数”或“这个人个方法”或“这个人要创建一个对象”

1.这些信息究竟是存在内存里的什么地方呢?

2.或者说用于描述这个整数、这些对象和方法的信息,都在哪呢?

3.这些内存的组织方式又是什么样的呢?

二、有三类不同的空间,但是其中两类与我们的关系最密切。

1.第一类存储空间:用于存储所有静态变量和常量

我们可以把它们想作不会变的变量,这是一块专门划分出来的空间,是一块比较特殊的空间,在这块特殊的空间存放着静态变量和常量,那么这特殊空间在何处呢,我们不是特别关心,总之它就是我们的特殊小可爱。

因为在程序开始运行的时候,这些东西就会被放置在内存中,我们的这些常量永远不会改变,这意味着他们并不需要被放在那些我们常常访问的内存中,他们只要呆在内存中的某个地方,然后我们知道如何访问它就可以了。

2.第二类存储空间:用于存储动态变量

1).什么是动态变量?

动态变量就是利用new申请到的变量,所以当你用new来申请一个对象的时候,比如new Goval(参数),这样就得到一个动态变量,动态变量对应的内存,也就是你用new申请到的叫做堆。

2).什么是堆?

堆就像是一大摞衣服,当你需要衣服的时候你过去说,“嘿,我需要些新衣服”然后它就给你些衣服,你穿完这些衣服就会说,“嘿,我再也不要穿这些衣服了”,然后神奇的事情就是,被你舍弃的衣服就变成了一块布,计算机知道你不再穿这些衣服了,它说,“我要把这些内存拿回来”,这就叫做垃圾回收。

垃圾回收的实质:当堆里的内存不再被需要的时候,就会被收回。

3.第三类存储空间:用于存储本地变量

这些本地变量存放在一个叫栈的地方

     什么是栈?

和堆的概念是不一样的。对栈来说,当你在某方法中访问本地变量时,或者说你在调用方法时要传递某些参数时,比如说这些参数,你实际上是把这些参数的值进行了复制,在内存中分配了另一块空间来存储它们,而时间上在栈中就会有一些空间会被自动分配给你,当你在访问本地变量后者是传递参数,或者是调用方法时,这些变量都是活跃的,而当这些变量不再活跃时,比如方法调用结束,或者遇到了右花括号时,这些变量就会消失,它们也就不能再会以任何形式被调用,然后栈就说到,“嘿,我要把这些内存空间拿回来”。

4.介绍静态变量、动态变量和本地变量

1)静态变量: 所有静态变量,或者叫特殊变量,都存储在内存中比较低的位置,也就是说,这些位置对应的数值都是比较小的,比如说在1000这个位置,注意这个1000是十六进制的而不是十进制的。

2)堆:当堆变大时它是在往下变大。往下变大是什么意思?这就是说当从2000开始的时候,你说,“嘿 堆 我需要给我的新GOval准备一些空间”它说,“好的 我给你在这里分配些内存,就在2004这个地方好啦”,然后你说,“我需要给我的新GWreck准备一些空间,它说“好的,2008这地方归你了,我会在这里这给分配空间”,所以说当堆越来越大的时候,我们就说堆在向下变大。

3)栈:栈从一些比较高的地址开始,从FFFF开始,当它分配内存时,它会向上变大。也就是说,这些地址数值会越来越小。还有一个参量用于描述本地变量、参数和动态变量,当然主要说的是动态变量。那就是它们所占用的空间大小。

4)不同变量实际上需要不同大小的存储空间,比如一个整数,int至少在C#,java占四个字节。动态变量还有一些附加内存开销,这实际上就是一些额外的内存空间,是整数和字符本身所占用空间外的一些空间,用来保存你的对象的其他信息。

三、在程序开始运行的时候,或者创建新对象的时候,到底发生了什么......

准备:

1.我们可以通过调用构造方法创建一个点,并告诉它x和y坐标,然后它就会把这个坐标保存下来,你就可以去移动这些点。

2.刚开始只是有这个类,内存尚未被分派,什么事还都没做。我们写个程序,创建点对象,并调用其对应的方法。运行程序,我们就可以知道在个过程中,计算机内存里到底发生了什么。

3.运行:

1)第一件事:调用run方法,当程序刚开始运行时run方法会被调用。

当一个方法被调用时,我们会创建这些本地变量和参数,但是run没有参数,所以不需要为参数安排空间,但它的确有两个本地变量P1和P2,但是还不包括任何信息,因为我的程序刚刚开始,还没运行到new Point这个地方。

2)第二件事:调用new便可以得到一个动态变量,这意味着它将被存储在堆里。

a.记录保存一个点的数据。构造方法的作用是将在计算机分配的空间填进数据(2,3)。

b.overhead里面是额外内存开销。

c.为什么在p1那里写1000呢?其实是我们给这个新的点分配好空间之后,该如何处理这个点呢?我们把这个点分配给P1,这里有个关键的知识点,就是计算机是怎么知道P1和它代表的所有信息都存储在那里呢?每个对象都有一个地址,实际上计算机在内部是通过对象所处的内存地址,来找到这些对象的。所以当我调用new的时候,就会在堆中申请一块空间。然后把这段空间赋值给p1,到底是什么东西被赋值了呢?实际上是把P1的内存地址进行了赋值,确切的讲是起始地址。通过这个起始地址可以找到P1包含的所有数据,这些数据就被存储在stack(1000)里,这里的1000是内存地址1000。

3)第三件事:新建一个新点,需要从堆那里要点内存。

堆说,“1008之前的地址已经分配出去了,那我就接着给你分配一块能放得下一个点的空间,用来保存你的实例变量。

然后计算机就说好,分配我一个空间,然后调用构造方法,将点的数据填入存储单元,再将起始地址100C赋值给p2。px、py是属于p1的实例变量,后来分配的px、py是属于p2的实例变量。

4)第四件事:神奇的事件。调用一个方法,例如调用p1.move。

a.当我们调用这个方法时,我们会有一些参数和本地变量。也就是说我们要在栈上分配内存才能进行方法的调用。所以当我们调用方法时所发生的就是,“嘿,p1我要把你移动一下偏移(10,11)这么多”。那再内存中发生了什么事呢?内存中发生的事情就是:我们会创建一个新的“栈帧”,当你调用一个方法的时候,调用方法的方法,或者说原先运行的方法就会被挂起。内部的情况是这样的,我们在栈上分配内存空间,所以我们管它叫栈帧,它存储了调用这个方法所需要的信息。什么信息,首先是方法的调用,额外内存开销,需要存储所有传进来的参数。

b.关于this,有一个隐藏参数,当我针对某特定对象调用方法后,我如何得知这个方法要调用的对象是哪个?当你对一个对象调用方法的时候,在所谓的内存开销之后,紧接着放在栈上的内容,实际上是指向这个对象的指针;我们把它叫做this指针。this是对象访问自己的一种方式。它需要知道自己在内存的某个地方。

c.很奇怪,为什么对象需要知道自己呆在什么地方呢?

因为当我们写一个方法的时候,我们并没有将这些方法跟已经创建的某些特定对象进行关联。如果我创建一个特定的对象(如p1),然后对其调用那个方法,那个方法得知道,“嘿,你让我改变px py值,你说的是那个px py值”,这个时候,this就起作用了。

this说:“我知道这个方法对应对象在内存中的位置。”这样无论你在程序里进行什么样的操作,都可以通过this指定你要访问的对象。

进行方法调用的时候,首先要知道这个方法所对应的那个特定的对象的地址。我们针对p1进行调用,p1放在1000这个位置。所以p1就是1000,指针this指的值就是1000.接下来逆序存放传入的参数。传入参数值,这些是传入参数的副本。

5)第五件事:现来看看调用move方法时会怎样?现在栈里面已经存储了move的本地变量,和对象对应的指针地址。

a.第五步执行的是px加10,但是是那个px呢?我们顺着this指针找到的那个px。

如何找?

b.去this存储的地址找。于是它到达1000位置那里,读取额外内存开销信息,它就知道px相对起始位置1000的位置。然后它继续说“嘿已经找到了,它的值是2,我在它上面加上10变成12”。

6)第六件事:很有趣的事情。当栈内变量不再活跃时,它们就会被删除。

a.这个时候计算机会自动跑过来说,“嘿,这块变量,这块内存,再也不会用到,我要把它收回。”所以栈上这部分的内存,就是与move方法相关的栈帧。这些就是调用move分配的内存。也就是说所有为move分配的内存被机器自动的收回。这就叫做"栈里弹出"。想象一下,当栈顶的东西用完后,把它从栈顶上弹出去,然后它就没有了。

b.如果再次调用move方法?相关的信息又会重新放在栈帧上,但执行过一次move之后就不需要了。

注意:构造方法和其他方法的区别,构造方法不用this指针。

(二)学习C#之内存管理的更多相关文章

  1. linux kernel学习笔记-5内存管理_转

    void * kmalloc(size_t size, gfp_t gfp_mask); kmalloc()第一个参数是要分配的块的大小,第一个参数为分配标志,用于控制kmalloc()的行为. km ...

  2. XV6学习笔记(2) :内存管理

    XV6学习笔记(2) :内存管理 在学习笔记1中,完成了对于pc启动和加载的过程.目前已经可以开始在c语言代码中运行了,而当前已经开启了分页模式,不过是两个4mb的大的内存页,而没有开启小的内存页.接 ...

  3. linux学习的任督二脉-进程调度和内存管理

    转自 宋宝华老师的博客原文:https://blog.csdn.net/21cnbao/article/details/77505330 内功心法 学习或遇到问题时,反过来主动思考如果我是设计者,我会 ...

  4. COCOS学习笔记--Cocod2dx内存管理(三)-Coco2d-x内存执行原理

    通过上两篇博客.我们对Cocos引用计数和Ref类.PoolManager类以及AutoreleasePool类已有所了解,那么接下来就通过举栗子来进一步看看Coco2d-x内存执行原理是如何的. / ...

  5. 嵌入式linux学习笔记1—内存管理MMU之虚拟地址到物理地址的转化

    一.内存管理基本知识 1.S3C2440最多会用到两级页表:以段的方式进行转换时只用到一级页表,以页的方式进行转换时用到两级页表.页的大小有三种:大页(64KB),小页(4KB),极小页(1KB).条 ...

  6. Linux内核学习笔记——内核内存管理方式

    一 页 内核把物理页作为内存管理的基本单位:内存管理单元(MMU)把虚拟地址转换为物理 地址,通常以页为单位进行处理.MMU以页大小为单位来管理系统中的也表. 32位系统:页大小4KB 64位系统:页 ...

  7. ios学习笔记之内存管理

    一,内存管理类型定义      1,基本类型  任何C的类型,eg:      int,short,char,long,long long,struct,enum,union等属于基本类型或结构体   ...

  8. cocos2d-x学习之自动内存管理

    一.自动内存管理 1)概述 C++语言默认是没有提供自动内存管理的.使用者需要自己分配,自己释放.在cocos2d-x里提供了一个自动内存管理的方案.主要是通过CCObject来提供的,用户只要继承了 ...

  9. 【IOS学习基础】内存管理

    1.内存几大区域 1> 栈区:局部变量(基本数据类型.指针变量). 2> 堆区:程序运行的过程中动态分配的存储空间(创建的对象). 3> BSS段:没有初始化的全局变量和静态变量. ...

随机推荐

  1. js 使用技巧 - [近几年工作中的经验总结的技巧]

    1.如果 ajax 返回单一的 json 格式,接收方需要这样再格式化一下赋值: var str = eval("(" + msg + ")"); 开发引用: ...

  2. 基于C#利用金山取词组件实现屏幕取词功能

    这个程序在网上有很多例子,近期要做的项目中有和这个有某些一点点相似的地方,就练练,发现在本机上(Win 7 64位)不能实现其功能,可能原因是API组件太老了吧,毕竟金山大佬公布他的组件是2005年, ...

  3. gridview 一个列勾选框选中,同时选中同一行的另一列勾选框

    <asp:TemplateColumn > <HeaderTemplate> 是否显示 <asp:CheckBox ID="chk_Show" sty ...

  4. HTML标签语义对照表

    标签名 英文全拼 中文翻译 div division 分隔 span span 范围 ol ordered list 排序列表 ul unordered list 不排序列表 li list item ...

  5. 2016 系统设计第一期 (档案一)MVC bootstrap model弹出窗

    局部代码: <!-- 按钮触发模态框 --> <div style=""> <button class="btn btn-primary&q ...

  6. iphone编程,使用代码结束程序

    (ios 4环境) 1.使用代码可以结束自己只有一种方式,而且apple不建议这样用,就是调用exit()函数.在2.0以前uiapplication类中有一个方法可以调用,但是现在已经没有了,而且如 ...

  7. 2338: [HNOI2011]数矩形 - BZOJ

    因为已经看了一眼题解,知道是算中点和长度,相同时构成一个矩形,所以就把所有的线段算出来,然后排序,相同的就更新答案 为了避免误差,我们都用整数存,中点直接相加就行了,没必要除2,长度也只要平方就行了, ...

  8. ASP.NET MVC 数据分页思想及解决方案代码

    作为一个程序猿,数据分页是每个人都会遇到的问题.解决方案更是琳琅满目,花样百出.但基本的思想都是差不多的. 下面给大家分享一个简单的分页器,让初学者了解一下最简单的分页思想,以及在ASP.NET MV ...

  9. iOS开发的小技巧(断点打印)

    iOS开发中我们会碰到这样的需求:打印沙盒目录,打印对象信息,对象信息可以通过断点查看,有时候对象属性繁多时看起来又比较麻烦. 今天学到一个比较实用的方法: 在运行时打一个断点,当程序停在这个断点后, ...

  10. 单独下载的Qt library则一般不带SSL(包括QT FAQ)

    http://www.cnblogs.com/E7868A/archive/2012/11/15/2771501.html http://www.oldcai.com/archives/208 htt ...