WhiteEngine-专注图形渲染与游戏引擎技术的网站

新浪微薄腾讯微薄

最新碎语:暂无碎语

您的位置:WhiteEngine-专注图形渲染与游戏引擎技术的网站 >C#与Lua> c#代码优化之栈和堆

c#代码优化之栈和堆

c#代码优化之栈和堆


首先了解下程序在内存中的基本分配方式:

1.栈:编译器自动分配释放,存储函数的参数,局部变量等。操作方式类似于数据结构中的栈。

2.堆:一般由程序员分配释放,根据不同平台和程序产生GC回收,或程序员释放。他们和数据结构中的堆和栈是两回事,分配方式类似于链表。

3.静态全局区:主要存储全局变量和静态变量。程序结束系统释放。

4.文字常量区:常量字符串存储,程序结束系统释放。

5.程序代码区:存放函数体二进制代码。


对栈和堆的理解:

        1.栈是编译期间就分配好的内存空间,因此你的代码中必须就栈的大小有明确的定义;堆是程序运行期间动态分配的内存空间,你可以根据程序的运行情况确定要分配的堆内存的大小


       2.存放在栈中时要管存储顺序,保持着先进后出的原则,他是一片连续的内存域,有系统自动分配和维护。


       3.而堆是无序的,他是一片不连续的内存域,有用户自己来控制和释放,如果用户自己不释放的话,当内存达到一定的特定值时,通过垃圾回收器(GC)来回收。


       4.使用.Net框架开发程序的时候,我们无需关心内存分配问题,因为有GC这个大管家给我们料理一切。


       5.栈内存无需我们管理,也不受GC管理。当栈顶元素使用完毕,立马释放。而堆则需要GC(Garbage collection:垃圾收集器)清理。



什么元素被分配到栈?什么被分配到堆?

        

当我们程序执行的时候,在栈和堆中分配有四种主要的类型:值类型,引用类型,指针,指令。

值类型:
在C#中,继承自System.ValueType的类型被称为值类型,主要有以下几种(CLR2.0中支持类型有增加):
    * bool
    * byte
    * char
    * decimal
    * double
    * enum
    * float
    * int
    * long
    * sbyte
    * short
    * struct
    * uint
    * ulong
    * ushort

引用类型:
以下是引用类型,继承自System.Object:
    * class
    * interface
    * delegate
    * object
    * string

指针:
在内存区中,指向一个类型的引用,通常被称为“指针”,它是受CLR( Common Language Runtime:公共语言运行时)管理,我们不能显示使用。需要注意的是,一个类型的引用即指针跟引用类型是两个完全不同的概念。指针在内存中占一块内存区,它本身只代表一个内存地址(或者null),它所指向的另一块内存区才是我们真正的数据或者类型。


如何分配?


       1.引用类型总是被分配在堆上。

       2.值类型和指针总是分配在被定义的地方,他们不一定被分配到栈上。

        2.1、引用类型内部的变量,即使是值类型,也会随同引用类型的实例一起被分配在堆上。

        2.2、对于值类型的数组,由于数组是引用类型,数组内的值类型元素,也被分配在堆上。

        2.3、对于闭包,如下:           

         Action<int> act = a =>
                {
                    Console.WriteLine(a);
                };

        C# compiler 生成的IL 会添加一个静态的辅助类,闭包内的局部变量 也会成为辅助类的成员变量,因此,这种值类型的局部变量也被分配到堆上。

       上文提及的栈(Stack),在程序运行的时候,每个线程(Thread)都会维护一个自己的专属线程堆栈。
当一个方法被调用的时候,主线程开始在所属程序集的元数据中,查找被调用方法,然后通过JIT即时编译并把结果(一般是本地CPU指令)放在栈顶。CPU通过总线从栈顶取指令,驱动程序以执行下去。

优化代码:

    1.如果是unity中,减少update中使用new来开辟内存空间。

    2.如果能用结构解决的事情尽量使用结构而非类。

    3.合理的手动GC回收内存,避免自动GC让程序处于挂起状态。

---

转载请注明本文标题和链接:《c#代码优化之栈和堆

发表评论

路人甲 表情
看不清楚?点图切换 Ctrl+Enter快速提交