Tag: 内存管理

在C#字符串对象之间共享字符缓冲区

这可能吗? 鉴于C#使用不可变字符串,可以预期会有一种方法: var expensive = ReadHugeStringFromAFile(); var cheap = expensive.SharedSubstring(1); 如果没有这样的function,为什么还要使字符串不可变呢? 或者,如果字符串由于其他原因已经不可变,为什么不提供此方法呢? 我正在研究的具体原因是做一些文件解析。 简单的递归下降解析器(例如由TinyPG生成的解析器,或者易于手工编写的解析器)在整个地方使用Substring。 这意味着如果你给他们一个大文件来解析,内存流失是令人难以置信的。 当然有解决方法 – 基本上滚动你自己的SubString类,然后当然忘记能够使用诸如StartsWith之类的String方法或像Regex这样的字符串库,所以你需要自己推出这些版本。 我假设像ANTLR这样的解析器生成器基本上就是这样做的,但我的格式很简单,不能certificate使用这样的怪物工具。 即使是TinyPG也可能是一种矫枉过正。 有人请告诉我,我错过了一些明显的或不那么明显的标准C#方法调用…

反序列化XML文件而不将其全部加载到内存中

假设您的应用程序使用XmlSerializer序列化对象。 当应用程序的另一部分(例如外部服务或其他组件)处理该xml文件时,会返回一个巨大的xml文件,该文件是一个巨大对象的序列化。 在不填充服务器内存的情况下,反序列化和处理响应的方法是什么? 我通常更喜欢使用XmlSerializer,但是当我必须对抗这些怪物时,我没有防弹解决方案。 我已经阅读了有关XNode.ReadFrom的内容,但我想知道如果使用这种方法,我可以像流式反序列化那样完成。 谢谢,马可

如果它在本地堆上分配,为什么称它为Marshal.AllocHGlobal?

从Marshal.AllocHGlobal的MSDN文档中: AllocHGlobal是Marshal类中的两种内存分配方法之一。 此方法从Kernel32.dll公开Win32 LocalAlloc函数。 考虑到有一个GlobalAlloc API在全局堆上而不是本地堆上分配内存,这个方法的名称不是误导吗? 是否有理由将其命名为AllocHGlobal ,而不是AllocHLocal ? 更新: Simon在评论中指出,Windows中不再存在全局堆,而GlobalAlloc和LocalAlloc API仅用于遗留目的。 目前, GlobalAlloc API不再是LocalAlloc的包装器。 这解释了为什么API根本不调用GlobalAlloc ,但它没有解释为什么API在没有(不能)使用全局堆时也被命名为AllocHGlobal ,甚至也没有调用GlobalAlloc 。 命名不可能是出于遗留原因,因为直到16位支持被删除后才会引入.NET 2.0。 所以,问题仍然存在:为什么Marshal.AllocHGlobal如此误导地命名?

每个用户定义的类是否需要实现IDisposable接口以获取垃圾

我不确定用户定义的类对象是如何被垃圾收集的。 我是否需要在每个类上实现IDisposable接口并调用dispose()方法来释放内存?

list.count是否在物理上迭代列表以对其进行计数,或者它是否保留指针

我正逐步通过一个大的对象列表来做一些有关列表中所述对象的东西。 在迭代期间,我将根据特定条件从列表中删除一些对象。 完成所有操作后,我需要更新有关列表中对象数量的UI。 (T列表)。 题: 当我调用list.count时,.net是否实际遍历列表来计算它,还是将计数存储为属性/变量? 如果.net在列表中进行物理重新迭代,我也可以通过列表在我自己的迭代中保留一个计数器,并节省开销? 谢谢

列出内存开销

我有这样的事情: List res = new List(); … while (…) { byte[] val = //get new byte[4] res.Add(val); //if this is commented memory usage goes from 2Gb to 180Mb } return res; 现在val总是字节[4],大约有37000000个元素。 所以我认为res应该在37 * 10 ^ 6 * 4字节= 148 MB左右,但实际内存使用量约为2GB。 如果我评论res.Add(val); 然后内存使用量大约为100 MB。 那么记忆在哪里? 编辑 我试图使用uint而不是byte [4],但结果是一样的: EDIT2 好吧,使用uint而不是byte [4] 和 List()而不是List将内存放到大约300 MB。

我可以“启动”CLR GC以期望使用挥霍的内存吗?

我们有一个服务器应用程序,它可以进行大量的内存分配(包括短期内存和长期内存)。 我们在启动后不久就看到了大量的GC2系列,但这些系列在一段时间后会冷静下来(即使内存分配模式不变)。 这些系列在早期就达到了性能。 我猜这可能是由GC预算引起的(对于Gen2?)。 有没有什么方法可以设置这个预算(直接或间接),以使我的服务器在开始时表现更好? 我看到的一组反直觉的结果:我们大大减少了内存(和大对象堆)分配的数量,这使得长期性能得到改善,但早期性能变差,并且“安定下来” “时间变长了。 GC显然需要一段时间来实现我们的应用程序是一个记忆猪并相应地适应。 我已经知道这个事实,我如何说服GC? 编辑 操作系统:64位Windows Server 2008 R2 我们正在使用.Net 4.0 ServerGC Batch Latency。 尝试了4.5和3种不同的延迟模式,虽然平均性能略有提高,但最差情况下的性能实际上已经恶化 EDIT2 GC峰值可以将从可接受时间到不可接受时间的时间加倍(我们正在谈论秒数) 几乎所有的峰值都与第2代集合相关 我的测试运行导致最终的32GB堆大小。 最初的泡沫持续时间为运行时间的第1个1/5,之后的性能实际上更好(峰值频率更低),即使堆正在增长。 测试结束时的最后一个峰值(具有最大堆大小)与初始“训练”期间的峰值中的2个(即坏)相同(具有更小的堆)

在服务器端提供指纹比较的最佳方法

我将通过WebAPI从服务器端提供指纹认证。 以下代码是指纹比较部分。 var allFingerprints = container.Fingerprints.OrderByDescending(p=>p.FingerprintID); List fmdList = new List(); foreach (var fp in allFingerprints) { fmdList.Add(Fmd.DeserializeXml(fp.FMD)); } IdentifyResult identifyResult = Comparison.Identify(customerFmd, 0, fmdList, thresholdScore, 2); 如果DB中有少量(<3000)指纹,我认为可以从DB读取指纹并进行比较。 但是,如果指纹的数量越来越大,服务器稍后会从客户端获得大量API调用,那么从数据库读取指纹并进行比较的最佳方法是什么? 我是否必须将指纹列表保留在内存中并进行比较? 感谢您提前提出的宝贵意见。

堆栈和堆在c锐利

可能重复: 当类存储在堆(.NET)上时,为什么结构存储在堆栈中? 任何人都可以告诉我如何分配内存以确定哪个对象存储在堆栈中以及哪些对象存储在内存的堆部分中?

堆内存问题

有一个WCF自托管服务,必须在99%的时间内工作。 有时我们会遇到一些像这样的内存问题: 但在此问题之后,服务正常。 我们如何管理这个? 任何提示和要点,以提供强大的服务,将在不同的情况下生存,非常受欢迎。