C#基础之内存分配
1.创建一个对象
一个对象的创建过程主要分为内存分配和初始化两个环节。在.NET中CLR管理的内存区域主要有三部分:栈、GC堆、LOH堆,栈主要用来分配值类型数据。它的管理是有系统控制的,而不是像GC堆那样是由GC控制的。当线程执行完值类型实例所在方法后,这块空间将会被自动释放,一般栈的执行效率高不过容量有限。GC堆用来分配小对象实例,它是由GC完全控制内存的分配和回收。LOH堆则是为大对象实例准备的,它不会被压缩且只在GC完全回收时才会回收。在IL中可以看到newobj、ldstr(创建string对象)、newarr(用于分配新的数组对象)、box(装箱)等常见的创建对象的指令。当然在堆上也存在值类型,比如值类型作为类的字段时,它将存储在堆中的实例对象空间,还有装箱时也会让堆上存在值类型。好了接下来我们来看看创建一个对象的内存分配,现在有一个Person类和Student类。那么这句Student s = new Student() { studentId = 2, Id = 4 };执行完后s对象就被创建了,下面我画了张图来说明创建一个对象时内存的分配,其中s对象还有同步索引块与类型对象指针我没有画出来。
public class Person
{
public int Id;
public void Eat()
{
Console.WriteLine("Eat Pear");
}
} public class Student:Person
{
public int studentId;
public void GotoSchool()
{
Console.WriteLine("Go to School");
}
}

2.父类对象指向子类
我们在写程序时为了实现多态一般都会使用父类对象指向子类。那么当我写入Person p=new Student();时便在堆中创建了一个子类对象,下面是关于父类对象指向子类的内存分配图。我在Person中添加了虚方法和抽象方法,并在Student子类重写了方法。从图中可以看出一旦子类重写了父类的虚方法或抽象方法,则Person方法表中的2个方法将会被子类覆盖,我们可根据它来实现多态。另外在Student方法表中还有一个new void Eat()方法,不过它是无法被p调用的因为此时的new Eat()属于子类。也就是说除了被覆盖的方法外,p只能调用Person方法表中的方法,如果找不到则会继续寻找Person父类的方法直到object。注意是不会往回找的,它不会去Student方法表中寻找方法。
public abstract class Person
{
public int Id;
public void Eat()
{
Console.WriteLine( "在吃梨");
}
public virtual void Walk()
{
Console.WriteLine("在散步");
}
//抽象方法只能在抽象类中声明,因此要在Person前加abstract,且只能声明并必须在子类中实现。
public abstract void Run();
}
public class Student:Person
{
public int studentId;
public void GotoSchool()
{
Console.WriteLine("Go to School");
} public new void Eat()
{
Console.WriteLine("学生 吃苹果");
}
public override void Walk()
{
Console.WriteLine("学生 在散步");
}
public override void Run()
{
Console.WriteLine("学生 在跑步");
}
}

3.指向孙类对象
现在我再添加一个Student的子类James,从上一个例子中已经知道只有override关键字重写的方法父类才会调用,因此我将普通方法全部删除。执行代码为Person p = new James() { name = "James", studentId = 2, Id = 4 };代码和内存分配图如下,为了突出重点,图中我就没有画字段了。从结果可以看到SayHi方法最后是被孙类的SayHi覆盖了,从这里可以看出继承的传递性!
public abstract class Person
{
public int Id;
public virtual void Eat()
{
Console.WriteLine( "在吃梨");
}
public virtual void Walk()
{
Console.WriteLine("在散步");
}
//抽象方法只能在抽象类中声明,因此要在Person前加abstract,且只能声明并必须在子类中实现。
public abstract void Run();
public virtual void SayHi()
{
Console.WriteLine("人说:你好!");
}
}
public class Student:Person
{
public int studentId;
public virtual void Eat()
{
Console.WriteLine("学生 在吃梨");
}
public override void Walk()
{
Console.WriteLine("学生 在散步");
}
public override void Run()
{
Console.WriteLine("学生 在跑步");
}
}
public class James:Student
{
public string name;
public override void Eat()
{
Console.WriteLine("James 在吃梨");
}
public override void Walk()
{
Console.WriteLine("James 在散步");
}
public override void Run()
{
Console.WriteLine("James 在跑步");
}
public override void SayHi()
{
Console.WriteLine("James说:你好!");
}
}

声明:本文原创发表于博客园,作者为方小白,如有错误欢迎指出 。本文未经作者许可不许转载,否则视为侵权。
C#基础之内存分配的更多相关文章
- java基础:内存分配(上)
java执行中的内存分区: 1.代码域:存放代码 2.数据域:存放静态的数据 3.栈:存放局部变量 4.堆:存放成员变量 (ps:局部变量是类中方法体中申明的变量,只在这个方法中有效:成员变量是类中方 ...
- Spark Tungsten揭秘 Day3 内存分配和管理内幕
Spark Tungsten揭秘 Day3 内存分配和管理内幕 恭喜Spark2.0发布,今天会看一下2.0的源码. 今天会讲下Tungsten内存分配和管理的内幕.Tungsten想要工作,要有数据 ...
- JAVA基础-栈与堆,static、final修饰符、内部类和Java内存分配
Java栈与堆 堆:顺序随意 栈:后进先出(Last-in/First-Out). Java的堆是一个运行时数据区,类的对象从中分配空间.这些对象通过new.newarray.anewarray和mu ...
- Java基础-Java中的内存分配与回收机制
Java基础-Java中的内存分配与回收机制 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一. 二.
- 数据结构基础(1)--数组C语言实现--动态内存分配
数据结构基础(1)--数组C语言实现--动态内存分配 基本思想:数组是最常用的数据结构,在内存中连续存储,可以静态初始化(int a[2]={1,2}),可以动态初始化 malloc(). 难点就是数 ...
- JVM基础知识2 垃圾收集器与内存分配策略
如何判断堆中的哪些对象可以被回收 主流的程序语言都是使用根搜索算法(GC Roots Tracing)判定对象是否存活 基本思路是:通过一系列名为“GC Roots”的对象作为起点,从这些节点开始向下 ...
- JVM基础学习(二):内存分配策略与垃圾收集技术
Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来 垃圾收集概述 Java内存模型中的堆和方法区是垃圾收集技术所需要关注的终点,因为其他的区域会跟 ...
- Java学习之旅基础知识篇:数组及引用类型内存分配
在上一篇中,我们已经了解了数组,它是一种引用类型,本篇将详细介绍数组的内存分配等知识点.数组用来存储同一种数据类型的数据,一旦初始化完成,即所占的空间就已固定下来,即使某个元素被清空,但其所在空间仍然 ...
- 数据结构基础——指针及动态内存分配(malloc)
一.指针 C语言中的指针是一种数据类型,比如说我们用int *a;就定义了一个指针a,它指向一个int类型的数.但是这个指针是未初始化的,所以,一般的,我们都在创建指针时初始化它,以免出错,在还不吃的 ...
随机推荐
- 如何在linux系统中设置静态ip地址
在终端中输入:vi /etc/sysconfig/network-scripts/ifcfg-eth0 开始编辑,填写ip地址.子网掩码.网关.DNS等.其中"红框内的信息"是必须 ...
- C# PDF打印
C#中使用iTextSharp生成并下载PDF很方便. 首先要将iTextSharp的dll下载并引入项目 主要分成两部分,一部分是PDF的Document生成,另一部分就是将Document输出到页 ...
- Python Memcached Script
介绍 利用 python 书写了 memcached 的启动等一类操作 尽量的实现脚本的复用性,以及脚本的可扩展性,已达到一劳永逸的效果, 并且添加了 memcached 监控搭建 memcached ...
- Adaboost 卡口车辆检测训练
之前做了SVM的车脸检测,主要是针对车脸,接下来尝试利用Adaboost和Haar进行车脸的检测.我利用的主要是opencv中的cascade,其已经把Adaboost相关的算法做成了exe,直接调用 ...
- 敬爱的GitHub” —— 致GitHub的一封地下信 英文原文:"Dear GitHub…" An Open Letter to GitHub
敬爱的GitHub” —— 致GitHub的一封地下信 英文原文:"Dear GitHub…" An Open Letter to GitHub 最近,一个由开源名目(包含一些最盛 ...
- 二分套二分 hrbeu.acm.1211Kth Largest
Kth Largest TimeLimit: 1 Second MemoryLimit: 32 Megabyte Description There are two sequences A and ...
- 传统高斯模糊与优化算法(附完整C++代码)
高斯模糊(英语:Gaussian Blur),也叫高斯平滑,是在Adobe Photoshop.GIMP以及Paint.NET等图像处理软件中广泛使用的处理效果,通常用它来减少图像噪声以及降低细节层次 ...
- UESTC 878 温泉旅馆 --性质+枚举
设FA为A的牌中数字异或和,FB为B的. 则有性质: ans = (所有的(A&B=0)个数 + (FA=FB且A&B=0)的个数)/2.即所有的FA>FB的个数(除2是因为这里 ...
- HDU 4455 Substrings --递推+树状数组优化
题意: 给一串数字,给q个查询,每次查询长度为w的所有子串中不同的数字个数之和为多少. 解法:先预处理出D[i]为: 每个值的左边和它相等的值的位置和它的位置的距离,如果左边没有与他相同的,设为n+8 ...
- UVALive 6656 Watching the Kangaroo --二分
题意:给你一些区间,再查询一些点,问这些点与所有区间形成的最小距离的最大值.最小距离定义为:如果点在区间内,那么最小距离为0,否则为min(pos-L[i],R[i]-pos). 解法:当然要排个序, ...