C# 值类型和引用类型、堆和栈值类型和引用类型

C# 值类型和引用类型、堆和栈值类型和引用类型

前者是现金,后者是存折

装箱就是值类型到引用类型的转化过程

在声明值类型变量时,如果没有初始化赋值,编译器会自动将其赋值为0,既然值类型没有引用,那么它就不可能为空。引用类型不一样,它可以为空引用,一张过期作废的银行卡是可以存在。而如果将一个空的对象拆箱,编译器上哪儿去找它里面的值类型变量的指针呢?所以这也是拆箱操作需要注意的地方。

1. 值类型的数据存储在内存的栈中;引用类型的数据存储在内存的堆中,而内存单元中只存放堆中对象的地址。

2. 值类型存取速度快,引用类型存取速度慢。

3. 值类型表示实际数据,引用类型表示指向存储在内存堆中的数据的指针或引用

4. 值类型继承自System.ValueType,引用类型继承自System.Object

5. 栈的内存分配是自动释放;而堆在.NET中会有GC来释放

C#中基本数据类型是值类型,结构也是值类型。而数组、类、接口、字符串都是引用类型。

http://blog.sina.com.cn/s/articlelist_1561545354_9_1.html

栈区(stack)— 由系统自动分配

堆区(heap) — 需要程序员自己申请,并指明大小,分配方式倒是类似于链表。

还有就是数据结构方面的堆和栈,这些都是不同的概念。这里的堆实际上指的就是(满足堆性质的)优先队列的一种数据结构,第1个元素有最高的优先权;栈实际上就是满足先进后出的性质的数学或数据结构。 

值类型引用类型内存分配地点分配在栈中分配在堆中效率效率高,不需要地址转换效率低,需要进行地址转换内存回收使用完后,立即回收使用完后,不是立即回收,等待GC回收赋值操作进行复制,创建一个同值新对象只是对原有对象的引用函数参数与返回值是对象的复制是原有对象的引用,并不产生新的对象类型扩展不易扩展容易扩展,方便与类型扩展


PS一个小应用程序,占的内存太大,你会怎么检查?

帖子中答案,不一定准确,做个参考:

这是一个很广的命题, 小应用程序是指什么,JS,EXE,CLR EXE,....

根据题意;我们假设是一个小的.NET程序。

再看有没有提供源码,有 DUBUG跟踪,找出托管资源有没有及时释放,有没有关系IO资源,...
否 看看能不能反汇编成源码, 代码可能混淆了,继续以上

如果都不能,使用进程跟踪工具,看看它是否再进行IO,SOCKET等资源操作。

如果都没有,假设程序内部做了一些死循环,多余的操作,错误的操作
……

1检查在同一时间处理的对象是否过多,举例就是,比如现在一次load十万条数据,可以改成一次一万条,分十次来,load一次处理一次,抛弃,load下一批; 
2比较耗费资源的操作在使用完后是否有立即释放内存资源



如果特指.net程序的话,首先要用perfmon来看是托管泄漏还是非托管泄漏,托管泄漏的话简单一些,windbg+sos,先!dumpheap -stat查看占用内存比较大的对象是哪些,找出methodtable后,用!dumpheap -mt命令随机找几个对象,找出对象地址,用!gcroot查看根在哪里,为什么没有被回收。另外注意的就是内存随便的问题,lmvm查看是否又太多的dll加载进来。如果!dumpheap里free的太多,也有可能是有内存碎片。托管的内存泄漏基本就是这样。如果是非托管内存泄漏,要修改注册表或者用gflag激活pageheap,发现内存占用比较大的时候,连续抓几次log,查看分配内存的调用栈,再结合代码来分析。非托管的内存分配涉及问题比较多,有用API分配的,有OLE分配的等等,得具体分析
原文地址:https://www.cnblogs.com/mingyongcheng/p/2869872.html