Tag: 内存管理

连续的内存存储误解在.NET?

http://msdn.microsoft.com/en-us/library/ms379570(v=vs.80).aspx 我知道.net中的Arrays是以连续的方式存储的。 (在mem中) 我也知道List不是。 (好吧……不是所有列表类型……请参阅我的第2个问题) 从这里我有2个问题 我知道在4,8,16 …插入项目到列表后 – 该列表在内存中reallocate自己。 我也知道我可以向他发送Capacity ,以便让他知道我将创建他的大小(以减少重新分配)。 问题是为什么 ? 他不会连续存放自己,为什么他关心重新分配自己呢? (他不必找到免费和连续的存储单元) 为什么带有结构的List是否在连续内存中分配,与类列表不同?

当我使用List 时,我在Jetbrains dotMemory中看到的这个“pinning handle object ”是什么?

我试图想出最简单的代码来重现我所看到的。 完整的程序如下,但我将在此处进行描述。 假设我有一个名为ListData ,它只有一些属性。 然后假设我有一个MyList类,它有一个成员List m_list 。 假设m_list在m_list构造函数中初始化。 在main方法中,我只需创建其中一个MyList对象,向其中添加一些ListData ,然后让它超出范围。 添加ListData后,我在dotMemory中拍摄快照,然后在MyList对象超出范围后再拍摄另一个快照。 在dotMemory中,我可以看到MyList对象已按预期回收。 我还看到我创建的两个ListData对象也按预期回收。 我不明白为什么有幸存的ListData[] ? 这是一个屏幕截图: 我在ListData[]的最新快照上打开幸存的对象,然后我查看Key Retention Paths,这就是我所看到的。 我是.NET内存管理的新手,我创建了这个示例应用程序来帮助我探索它。 我下载了JetBrains dotMemory版本4.3的试用版。 我正在使用Visual Studio 2013 Professional。 我必须学习内存管理,这样才能解决我们在工作中遇到的内存问题。 这是完整的程序,可用于重现这一点。 它只是一个快速而肮脏的应用程序,但如果你对它进行分析,它会得到我要问的东西。 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { class ListData { public ListData(string name, int n) { Name = name; Num […]

处理StringBuilder对象

如何有效地处理StringBuilder对象? 如果用户一次性生成多个报告,我的应用程序最终会占用大量内存。 我在线阅读了几个网站,以下内容可能有所帮助: StringBuilder sb = new StringBuilder(1000000); // loop goes here adding lots of stuff to sb exampleObject.Text = sb.ToString(); sb.Length = 0; 最后一行真的有帮助吗? 还有其他任何处理方法吗? 注意:这并没有真正阻止我的用户继续使用该应用程序。 我只是想知道是否有办法避免冗余内存使用。

结构内存破解重叠对象引用 – 是否可能?

我猜这个问题的答案是“这是不可能的,切换到C ++”。 但我还以为我会把它扔出去。 我正在处理一个巨大的二叉树。 我有一个结构数组来表示我在迭代树时用来帮助处理内存的分支节点。 为了节省一点内存,从而改善缓存局部性,我正在考虑重叠叶节点的对象引用。 该对象引用将指向所有叶数据。 基本上,这样的事情: [StructLayout(LayoutKind.Explicit)] struct BranchData { [FieldOffset(0)] // 1 byte internal byte SplitIndex; [FieldOffset(1)] // 4 bytes internal float SplitValue; [FieldOffset(5)] // 4 bytes internal int LowIndex; [FieldOffset(9)] // 4 bytes internal int HighIndex; [FieldOffset(0)] // 8 bytes (We’re working with x64 here) internal LeafData Node; } 以上给出了以下运行时错误 无法从程序集“WindowsFormsApplication1,Version […]

如何在C#中分配超过MaxInteger字节的内存

我希望分配超过MaxInteger字节的内存。 Marshall.AllocHGlobal()需要一个整数 – 所以我不能使用它。 还有另一种方式吗? 更新 我将平台更改为x64,然后运行下面的代码。 myp似乎长度合适:大约3.0G。 但固执地“缓冲”最高可达2.1G。 知道为什么吗? var fileStream = new FileStream( “C:\\big.BC2”, FileMode.Open, FileAccess.Read, FileShare.Read, 16 * 1024, FileOptions.SequentialScan); Int64 length = fileStream.Length; Console.WriteLine(length); Console.WriteLine(Int64.MaxValue); IntPtr myp = new IntPtr(length); //IntPtr buffer = Marshal.AllocHGlobal(myp); IntPtr buffer = VirtualAllocEx( Process.GetCurrentProcess().Handle, IntPtr.Zero, new IntPtr(length), AllocationType.Commit | AllocationType.Reserve, MemoryProtection.ReadWrite); unsafe { byte* pBytes = […]

是否可以在不使用分析器的情况下跟踪C#应用程序中的内存使用情况?

我想编写一个简单的应用程序来跟踪它当前的内存使用情况,创建的对象的数量等。在C ++中,我通常会覆盖new运算符,但由于显而易见的原因,我无法在C#中执行此操作。 没有使用探查器,有没有办法做到这一点?

来自队列的大对象堆和字符串对象

我有一个Windows控制台应用程序应该运行几天和几个月没有重新启动。 该应用程序从MSMQ检索“工作”并处理它。 有30个线程同时处理工作块。 来自MSMQ的每个工作块大约为200kb,其中大部分工作块分配在单个String对象中。 我注意到,在处理了大约3-4千个这些工作块之后,应用程序的内存消耗非常高,消耗了1到1.5 GB的内存。 我通过分析器运行应用程序并注意到大部分内存(可能是一个演出)在大对象堆中未使用但结构是分段的。 我发现这些未使用的(垃圾收集)字节中有90%是先前分配的字符串。 我开始怀疑从MSMQ进来的字符串是分配,使用然后解除分配,因此是碎片的原因。 我明白像GC.Collect(2或GC.Max …)这样的东西不会有用,因为它们是gc大对象堆但不压缩它(这是问题)。 所以我认为我需要的是缓存这些字符串并以某种方式重用它们,但由于字符串是不可变的,我将不得不使用StringBuilders。 我的问题是:无论如何不改变底层结构(即使用MSMQ,因为这是我无法改变的),并且仍然避免每次初始化一个新的String以避免分裂LOH? 谢谢,雅尼斯 更新:关于如何检索这些“工作”块 目前,它们作为WorkChunk对象存储在MSMQ中。 这些对象中的每一个都包含一个名为Contents的String和另一个名为Headers的String。 这些是实际的文本数据。 如果需要,我可以将存储结构更改为其他内容,如果需要,可以将底层存储机制更改为MSMQ以外的其他内容。 目前我们在工作节点方面 WorkChunk chunk = _Queue.Receive(); 所以在这个阶段我们几乎无法缓存。 如果我们以某种方式改变了结构,那么我想我们可以做一些进步。 在任何情况下,我们都必须解决这个问题,以便我们尽一切可能避免浪费数月的工作。 更新:我继续尝试下面的一些建议并注意到这个问题无法在我的本地计算机上运行(运行Windows 7 x64和64位应用程序)。 这使得事情变得更加困难 – 如果有人知道为什么那么它真的有助于在本地重新调整这个问题。

C#中的垃圾收集没有进行。 为什么?

我尝试过一个简单的实验来validation垃圾收集器的function。 引用3.9关于.NET中自动内存管理的自动内存管理 (MSDN)。 对我来说,它听起来像是C ++中的共享指针。 如果对象的引用计数器变为零,则它将被垃圾收集器解除分配。 所以我尝试在主窗体中创建一个函数。 该函数在我的主窗体的Shown事件函数内调用,该函数在构造函数之后执行。 这是实验代码。 public void experiment() { int[] a = new int[100000]; int[] b = new int[100000]; int[] c = new int[100000]; int[] d = new int[100000]; a = null; b = null; c = null; d = null; } 以下是结果: 在内存分配之前 内存分配后 在离开function范围之前 离开function范围后 为什么垃圾收集器即使在设置为null之后也不释放由数组a,b,c,d分配的内存?

在.NET中具有深度inheritance的类的内存分配

如果我有类A, B, C, D, E ,以及X, Y, Z和模型等接口,那么系统就像: class B : A, X class C : B, Y class D : C, Z class E : D 如果A是一个抽象基类而E是感兴趣的类,当我创建一个E实例时,它会依次创建A, B, C, D, X, Y, Z实例吗? 如果是这种情况,这会产生巨大的性能开销吗? 不是内存,而是运行时和GC明智。

C#大对象和堆

我对堆中大对象的存储感到有点困惑。比如对象的大小是多大? 什么类型更可能被视为大型对象?是否有适合管理此类对象的明确碎片方法。