微软的Visual C#2008年减少加载的DLL数 [英] Microsoft Visual C# 2008 Reducing number of loaded dlls

查看:177
本文介绍了微软的Visual C#2008年减少加载的DLL数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当在调试器中运行一个Visual C#项目中,我得到一个OutOfMemoryException因到2GB的虚拟地址空间的分段和我们假设加载的DLL可能是破碎的原因。

When running a visual C# project in the debugger I get an OutOfMemoryException due to fragmentation of 2GB virtual address space and we assume that the loaded dlls might be the reason for the fragmentation.


(更多信息请参阅下面的问题 - 发展史)

(for more information see history of question-development below)














我需要在内存中加载〜120万台(〜470MB)每两个大INT-阵列,并且都在一个Visual C#项目。

Hi, I need two big int-arrays to be loaded in memory with ~120 million elements (~470MB) each, and both in one Visual C# project.

当我试图实例第2个数组我得到一个OutOfMemoryException。

When I'm trying to instantiate the 2nd Array I get an OutOfMemoryException.

我有足够的总的可用内存和做后网络搜索我想我的问题是,有没有我的系统上足够大的连续可用内存块。
,而! - 当我实例只在一个的Visual C#实例的阵列之一,然后打开另一个Visual C#时,第二个实例可以实例化470MB的数组。
(编辑澄清:在段落上方我的意思是在Visual C#中调试器中运行它)

I do have enough total free memory and after doing a web-search I thought my problem is that there aren't big enough contiguous free memory blocks on my system. BUT! - when I'm instantiating only one of the arrays in one Visual C# instance and then open another Visual C# instance, the 2nd instance can instantiate an array of 470MB. (Edit for clarification: In the paragraph above I meant running it in the debugger of Visual C#)

和任务管理器显示相应的存储用途区内─加大就像你期望的那样。对整个系统
所以没有足够的连续内存块是没有问题的。然后我试图运行一个编译的可执行文件实例化两个数组其作品也(内存使用1GB)

And the task-manager shows the corresponding memory usage-increase just as you would expect it. So not enough contiguous memory blocks on the whole system isn't the problem. Then I tried running a compiled executable that instantiates both arrays which works also (memory usage 1GB)

摘要:

OutOfMemoryException异常在Visual C#中使用两个大INT阵列,但在运行编译EXE工程(MEM使用1GB)和两个独立的Visual C#实例都能够找到两个足够大的连续内存块我的大数组,但我需要的Visual C#实例。能够提供存储器

OutOfMemoryException in Visual C# using two big int arrays, but running the compiled exe works (mem usage 1GB) and two separate Visual C# instances are able to find two big enough contiguous memory blocks for my big arrays, but I need one Visual C# instance to be able to provide the memory.

所有特别感谢nobugz和布赖恩·拉斯穆森首先,我认为他们是发现与自己的预测:过程2GB的虚拟地址空间碎片就是这个问题。

First of all special thanks to nobugz and Brian Rasmussen, I think they are spot on with their prediction that "the Fragmentation of 2GB virtual address space of the process" is the problem.

随着他们的建议我使用的VMMap和listdlls的为我的短业余的分析,我也得到:结果
*为独立-exe上市21的DLL。 (在一个工程,并使用1GB内存)为vshost.exe版上市的结果
* 58的DLL。 (这是调试和抛出异常,并只使用500MB的运行时的版本)

Following their suggestions I used VMMap and listdlls for my short amateur-analysis and I get:
* 21 dlls listed for the "standalone"-exe. (the one that works and uses 1GB of memory.)
* 58 dlls listed for vshost.exe-version. (the version which is run when debugging and that throws the exception and only uses 500MB)

的VMMap表现出我要的调试版最大的空闲内存块是262,175,167,155,108MBs。结果
这样的VMMap说,没有连续的500MB块,并根据有关我加〜9小INT-阵列这加起来超过1,2GB内存使用更加自由块信息和实际做的工作。< BR>
所以从这一点我想说,我们可以称之为2GB的虚拟地址空间碎片化有罪的。

VMMap showed me the biggest free memory blocks for the debugger version to be 262,175,167,155,108MBs.
So VMMap says that there is no contiguous 500MB block and according to the info about free blocks I added ~9 smaller int-arrays which added up to more than 1,2GB memory usage and actually did work.
So from that I would say that we can call "fragmentation of 2GB virtual address space" guilty.

从listdll输出我创建了一个小电子表格与十六进制数转换为十进制检查的dll之间的自由区,我找到了单机版插图中(21)的dll而不是为vshost调试器版本(58 DLL)的大的自由空间。我并不是说不可能有什么别的之间,我真的不知道,如果我在做什么也有道理,但它似乎与VMMaps分析是一致的,它似乎犹如dll文件已经单独为分段记忆调试器版本。

From the listdll-output I created a small spreadsheet with hex-numbers converted to decimal to check free areas between dlls and I did find big free space for the standalone version inbetween (21) dlls but not for the vshost-debugger-version (58 dlls). I'm not claiming that there can't be anything else between and I'm not really sure if what I'm doing there makes sense but it seems consistent with VMMaps analysis and it seems as if the dlls alone already fragment the memory for the debugger-version.

因此,或许一个解决办法是,如果我将能够降低调试器。结果
1中使用的DLL的数量。 那可能吗?
2,如果是我会怎么做。

So perhaps a solution would be if I would be able to reduce the number of dlls used by the debugger.
1. Is that possible? 2. If yes how would I do that?

推荐答案

3日更新:你可以显著通过禁用的Visual Studio宿主进程(项目属性,调试)减少加载的DLL的数量。这样做将仍然允许你调试应用程序,但它会摆脱大量的DLL和一些辅助线程的为好。

3rd update: You can reduce the number of loaded DLLs significantly by disabling the Visual Studio hosting process (project properties, debug). Doing so will still allow you to debug the application, but it will get rid of a lot of DLLs and a number of helper threads as well.

在一个小的测试项目,从69到34加载的DLL的数量,当我禁用宿主进程。我也摆脱了10+线程。所有在内存使用全部显著减少也应有助于减少堆碎片。

On a small test project the number of loaded DLLs went from 69 to 34 when I disabled the hosting process. I also got rid of 10+ threads. All in all a significant reduction in memory usage which should also help reduce heap fragmentation.

在托管过程中附加信息:的 http://msdn.microsoft.com/en-us/library/ms242202.aspx

Additional info on the hosting process: http://msdn.microsoft.com/en-us/library/ms242202.aspx

可以装载在一个新的应用程序的第二阵列的原因在于每个进程得到一个完整的2 GB的虚拟地址空间。即操作系统将交换的网页以允许每个进程来解决存储器的总量。当您尝试在一个进程分配两个阵列运行时必须能够分配所需大小的两个连续块。你在阵列中的存储?如果存储的对象时,需要对每个对象附加空间。

The reason you can load the second array in a new application is that each process gets a full 2 GB virtual address space. I.e. the OS will swap pages to allow each process to address the total amount of memory. When you try to allocate both arrays in one process the runtime must be able to allocate two contiguous chunks of the desired size. What are you storing in the array? If you store objects, you need additional space for each of the objects.

记住一个应用程序并不实际要求的物理内存。代替每个应用程序被赋予从它们可以分配的虚拟存储器中的地址空间。操作系统将映射虚拟内存到物理内存。这是一个相当复杂的过程(Russinovich的花费在Windows如何处理内存超过100页在他的Windows内部的书)。有关Windows如何这是否请参阅 HTTP的更多详细信息://博客.technet.com / markrussinovich /存档/ 2008/11/17 / 3155406.aspx

Remember an application doesn't actually request physical memory. Instead each application is given an address space from which they can allocate virtual memory. The OS then maps the virtual memory to physical memory. It is a rather complex process (Russinovich spends 100+ pages on how Windows handle memory in his Windows Internal book). For more details on how Windows does this please see http://blogs.technet.com/markrussinovich/archive/2008/11/17/3155406.aspx

更新:我一直思考这个问题了一会儿,这听起来有点奇怪。当您运行通过Visual Studio应用程序,您可能会看到根据您的配置加载额外的模块。在我的设置,我得到了一些因探查和TypeMock(通过探查钩基本上做它的魔法)调试过程中加载的DLL不同的。

Update: I've been pondering this question for a while and it does sound a bit odd. When you run the application through Visual Studio, you may see additional modules loaded depending on your configuration. On my setup I get a number of different DLLs loaded during debug due to profilers and TypeMock (which essentially does its magic via the profiler hooks).

根据这些尺寸和负载地址,但他们可能会阻止运行时从分配连续的内存。话虽如此,我还是有点惊讶,你作为他们的组合大小小于1 GB分配只有两个那些大阵后得到一个OOM。

Depending on the size and load address of these they may prevent the runtime from allocating contiguous memory. Having said that, I am still a bit surprised that you get an OOM after allocating just two of those big arrays as their combined size is less than 1 GB.

您可以看看加载的DLL使用 listdlls的工具来自Sysinternals的。它会告诉你加载地址和大小。或者,您可以使用WinDbg。在流明命令显示加载的模块。如果你想大小以及你需要指定 v 选项详细的输出。 WinDbg中还可以让你检查.NET堆,它可以帮助你查明为什么内存不能进行分配。

You can look at the loaded DLLs using the listdlls tools from SysInternals. It will show you load addresses and size. Alternatively, you can use WinDbg. The lm command shows loaded modules. If you want size as well, you need to specify the v option for verbose output. WinDbg will also allow you to examine the .NET heaps, which may help you to pinpoint why memory cannot be allocated.

2日更新:如果您使用的是Windows XP,则可以尝试的变基一些加载的DLL,以腾出更多的连续空间? Vista和Windows 7使用 ASLR 的,所以我不相信你会从衍合在这些平台上获益。

2nd Update: If you're on Windows XP, you can try to rebase some of the loaded DLLs to free up more contiguous space. Vista and Windows 7 uses ASLR, so I am not sure you'll benefit from rebasing on those platforms.

这篇关于微软的Visual C#2008年减少加载的DLL数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆