Tag: memory management

为什么GC不收集未使用的对象?

我为我的实验用BlockingCollection实现了Producer / Consumer模式。 PerformanceCounter c = null; void Main() { var p =System.Diagnostics.Process.GetCurrentProcess(); c = new PerformanceCounter(“Process”, “Working Set – Private”, p.ProcessName); (c.RawValue/1024).Dump(“start”); var blocking = new BlockingCollection(); var t = Task.Factory.StartNew(()=>{ for (int i = 0; i Path.GetRandomFileName())) }); } blocking.CompleteAdding(); }); var t2 = Task.Factory.StartNew(()=>{ int x=0; foreach (var element in blocking.GetConsumingEnumerable()) { […]

XNA:Unload()有什么意义?

XNA游戏有一个Unload()方法,其中内容应该被卸载。 但这有什么意义呢? 如果正在卸载所有内容,那么游戏必须退出,在这种情况下,一切都将被垃圾收集,对吧?

访问c#中的内存地址

我正在连接一个ActiveX组件,它给我一个内存地址和字节数。 如何编写一个C#程序来访问从给定内存地址开始的字节? 有没有办法本机化,或者我将不得不与C ++接口? ActiveX组件和我的程序共享相同的内存/地址空间吗?

分页活动内存到磁盘的速率非常高,但内存使用率却很低

正如标题所述,我遇到了高页面文件活动的问题。 我正在开发一个处理大量图像的程序,它从硬盘加载。 它从每个图像生成一些数据,我保存在列表中。 对于每3600张图像,我将列表保存到硬盘驱动器,其大小约为5到10 MB。 它运行速度尽可能快,因此最多可以输出一个CPU线程。 该程序工作,它生成它应该的数据,但是当我在Visual Studio中分析它时,我得到一个警告说: DA0014:极高的分页活动内存到磁盘的速率 。 根据任务管理器,该程序的内存消耗约为50 MB,似乎是稳定的。 当我运行该程序时,我从4 GB中剩下大约2 GB,所以我想我没有用完RAM。 http://i.stack.imgur.com/TDAB0.png 例如,DA0014规则说明“输出的页数/秒通常远大于页面写入数/秒。因为Pages Output / sec还包括来自系统文件缓存的已更改数据页面。但是,它不是总是很容易确定哪个进程直接负责分页或为什么。“ 这是否意味着我得到这个警告只是因为我从硬盘驱动器中读取了很多图像,还是其他的东西? 不确定我正在寻找什么样的错误。 编辑:链接到插入的图像。 EDIT1:图像大小各约为300 KB。 在加载下一个之前,我将每个人都给它。 更新:从实验看起来像分页来自加载大量文件。 由于我不是C#或底层GDI + API的专家,我不知道哪个答案最正确。 我选择了Andras Zoltans的答案,因为它得到了很好的解释,因为他似乎做了很多工作来向像我这样的新人解释原因:)

读取二进制文件时避免LOH

此问题是将许多二进制文件传输到SQL Server数据库的有效方法的后续操作 我最初问为什么使用File.ReadAllBytes导致快速内存使用,并且使用该方法得出结论将数据放在大对象堆上,这在运行时期间无法轻易回收。 我现在的问题是如何避免这种情况? using (var fs = new FileStream(path, FileMode.Open)) { using (var ms = new MemoryStream()) { byte[] buffer = new byte[2048]; int bytesRead; while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0) { ms.Write(buffer, 0, bytesRead); } return new CustomFile { FileValue = ms.ToArray() }; } } 下面的代码旨在通过以块的forms而不是一次性读取文件来解决问题,但它似乎有同样的问题。

引发/生成空引用exception背后的CLR实现是什么?

我们确实遇到过这个特殊问题,也是我们编码/开发生活日或其他日子中最常见的例外情况之一。 我的问题不是 为什么 (我知道当我们尝试访问实际指向null的引用变量的属性时它会引发),但它是关于CLR 如何生成NULL REFERENCE EXCEPTION。 有时我被迫认为用于标识对null的引用的机制(可能null是内存中的保留空间)然后通过CLR引发exception。 CLR如何识别并引发此特定exception。 操作系统在其中起任何作用吗? 我想与大家分享一个最有趣的主张: null实际上是CLR已知的所有时间保留的内存空间,并且禁止所有类型的访问。 因此,当找到该空间的引用时,它默认通过OS生成访问被拒绝的exception类型,CLR将其解释为NULL引用exception。 我没有找到支持上述陈述的任何文章或post,因此很难相信。 可能由于我缺少挖掘细节或其他原因,我希望Stackoverflow是最合适的平台之一,我会得到最好的响应。

c#picturebox内存释放问题

我是C#的新手。 我必须在工作线程中重复刷新GUI图片框。 从使用GetImage方法轮询驱动程序的相机获取图像,该方法检索要显示的图像。 即使我使用指令“using”分配位图并显式调用GC,内存似乎永远不会被释放。 工作线程是这样的: while (true) { // request image with IR signal values (array of UInt16) image = axLVCam.GetImage(0); lut = axLVCam.GetLUT(1); DrawPicture(image, lut); //GC.Collect(); } 虽然DrawPicture方法是类似的 public void DrawPicture(object image, object lut) { […] // We have an image – cast it to proper type System.UInt16[,] im = image as System.UInt16[,]; float[] […]

在C#中使用Finalizer的好样本

当我在C#中阅读一些关于内存管理的文章时,我对Finalizer方法感到困惑。 有许多与之相关的复杂规则。 例如,没有人知道终结器何时被调用,即使ctor中的代码抛出,他们也会调用,CLR不保证在程序关闭时调用所有终结器等。 对于什么终结器可以在现实生活中使用? 我发现的唯一一个例子是程序在GC启动时发出蜂鸣声。 您是否在代码中使用了Finalizer并且可能有一些好样本? UPD: 当开发人员想要确保某些类始终通过IDisposable正确处理时,可以使用终结器。 ( 链接 ;感谢Steve Townsend )

MonoTouch:应用程序因低内存而被杀,为什么? 实时字节分配5 MB顶部

我的iPad应用程序是用MonoTouch开发的,因为我想避免所有的内存管理地狱,但事实并非如此。 在模拟器上一切正常,但是当我在设备上测试我的应用程序时,我惊恐地发现它在一些内存警告后很快被操作系统杀死了。 我的应用程序是一个简单的图像浏览器,它加载一些PNG图像并使用UIScrollView中的一些UIViews显示它们,在触摸时加载下一个或前一个。 在模拟器上它工作正常。 但是在加载和卸载大约6-11个图像后的设备上,它开始获得内存警告,然后突然该过程被杀死。 我检查了所有的实例循环,并在加载新图像之前正确删除了所有引用。 所以我启动了仪器并开始在iPad上分析我的应用程序的内存分配。 在那里,我发现Live字节只有大约5-9 MB,正如我所期望的那样,但由于一些奇怪的原因,死内存分配几乎完全没有收集,因为在分配了大约50 MB(小于5-9 MB的它是Live Bytes)它被杀了! 以下是我的应用程序的Instruments分析会话的屏幕截图: 这是快照序列: 还有一些小漏洞,但我认为它们不够大,不足以成为罪魁祸首。 它们都是来自strdup的48个字节泄漏,这是在iOS 5.1中发布UIScrollView时的一个已知问题: 即使一切看起来还不错,分配的Live Bytes仍然是5 MB,我的应用程序的REAL内存呈指数级增长,然后在iPad上被杀死高达50MB,而iPhone4S上的高达314 MB,如内存监视器所报告: 有人可以告诉我是否有方法或实用工具来发现问题的原因和位置? 这是一个单调垃圾收集器的错误吗? 还是有一些我没有正确处理的物体? 我怎么能用剖面仪找到那些? 我已经检查了两天我的代码,但一切似乎都正确。 这是我的加载/实例化/处置周期的代码: void StartImageLoadingThread() { tokenSource = new CancellationTokenSource (); token = tokenSource.Token; Task task1 = new Task( () => PerformLoadImageTask(token),token); task1.Start(); } void PerformLoadImageTask(CancellationToken token) { if (token.IsCancellationRequested) { […]

C#中的Volatile和Thread.MemoryBarrier

为了实现multithreading应用程序的无锁代码 ,我使用了volatile变量, 理论上 : volatile关键字用于确保所有线程都能看到volatile变量的最新值; 因此,如果线程A更新变量值,并且线程B在更新发生之后读取该变量,它将看到最近从线程A写入的最新值。正如我在Nutshell书中的C#4.0中读到的那样,这是不正确的,因为 应用volatile不会阻止写入后读取交换。 可以通过在每次获取volatile变量之前放置Thread.MemoryBarrier()来解决这个问题: private volatile bool _foo = false; private void A() { //… Thread.MemoryBarrier(); if (_foo) { //do somthing } } private void B() { //… _foo = true; //… } 如果这解决了问题; 考虑我们有一个while循环,它依赖于其中一个条件的值; 在while循环之前放置Thread.MemoryBarrier()是解决问题的正确方法吗? 例: private void A() { Thread.MemoryBarrier(); while (_someOtherConditions && _foo) { // do somthing. } […]