堆栈与.NET中的堆

dot*_*ner 14 .net c# vb.net heap stack

在您的实际编程经验中,STACK和HEAP的这些知识如何在现实生活中拯救您?来自战壕的任何故事?或者这个概念是否适合填写编程书籍并有利于理论?

lep*_*pie 16

.NET中引用类型和值类型的语义之间的区别是一个更为重要的概念.

就个人而言,在我多年的编码过程中,我从未想过堆栈或堆栈(仅基于CLR).

  • @Reed,我完全不同意.使用Heap与Stack来解释引用与值类型语义通常会导致混淆和虚假信息. (6认同)

Dav*_*ack 12

对我来说,这是"开发者/程序员"和"工匠"之间的区别.任何人都可以学习编写代码,看看事情是如何"神奇地发生",因为你不知道为什么/如何.为了真正有价值,我认为尽可能多地了解您正在使用的框架是非常重要的.请记住,它不仅仅是一种语言,它还可以用来为您的能力创建最佳应用程序.

多年来我分析了许多内存转储,发现知道内部和两者之间的差异非常有用.其中大多数都是OutOfMemory条件和不稳定的应用程序.在查看转储时,使用WinDbg绝对需要这些知识.在研究内存转储时,了解内核/用户模式进程与CLR之间如何分配内存至少可以告诉您从何处开始分析.

例如,让我们看一个OOM案例:您在堆大小,工作集,专用内存,共享内存,虚拟内存,提交内存,句柄和线程中看到的已分配内存可以作为从哪里开始的重要指标.

CLR使用大约8种不同的堆:

  1. Loader Heap:包含CLR结构和类型系统
  2. 高频堆:静态,MethodTables,FieldDescs,接口映射
  3. 低频堆:EEClass,ClassLoader和查找表
  4. Stub Heap:CAS,COM包装器,P/Invoke的存根
  5. 大对象堆:需要超过85k字节的内存分配
  6. GC堆:用户分配的堆内存专用于应用程序
  7. JIT代码堆:由mscoreee(执行引擎)分配的内存和托管代码的JIT编译器
  8. 进程/基本堆:互操作/非托管分配,本机内存等

查找具有高分配的堆可以告诉我是否存在内存碎片,托管内存泄漏,互操作/非托管泄漏等.

知道你为应用程序使用的每个线程分配的1MB(在x86上)/ 4MB(在x64上)的堆栈空间提醒我,如果我有100个线程,你将有额外的100MB虚拟内存使用量.

我有一个客户端,Citrix服务器因OutOfMemory问题而崩溃,不稳定,响应速度慢,当他们的应用程序在多个会话中运行时.在查看转储(我无法访问服务器)之后,我看到该应用程序实例使用了700多个线程!知道线程堆栈分配,允许我关联OOM是由高线程使用引起的.

简而言之,由于我为自己的"角色"所做的一切,所以拥有它是非常宝贵的知识.当然,即使你没有调试内存转储,它也不会受到伤害!


Eri*_*ert 11

当构建编译器时,理解它的区别当然是有帮助的.

以下是一些关于内存管理中的各种问题如何影响C#语言和CLR的设计和实现的文章:

http://blogs.msdn.com/ericlippert/archive/tags/Memory+Management/default.aspx