我注意到通常的内存大小很高。我编写的一个应用程序是一个控制台应用程序,它使用 <50 行,并且仅使用 WebRequest 下载一系列文件。另一个不简单的应用程序(mysql、dls、多线程、包含 100 个项目的列表框)。第一个使用 21 MB(调试、IDE),另一个使用 39MB(调试、IDE)。我还有另一个应用程序轮询我的网站(也使用 WebRequest)以获取状态更新,该更新位于我的托盘上,并使用 26mbs(发布,不通过 ide 运行)通知我。
为什么这些这么高?我知道我使用curl编写了一个与上面类似的C++应用程序,运行<2mb,而我最大的C++ prj是11mb,它加载在100kb dll和200kb二进制文件中(使用带有win32图标和声音的directx)。我如何编译我的 C# 代码,使其更节省空间。我想将它们部署到可能只有 128 或 256mb 内存的服务器,其中一些应用程序会杀死它。
站点注释:我在发布模式下(并通过 ide)运行了提到的第一个应用程序(控制台 DLer),它的大小跃升至 32mb。为什么!?!这更令人困惑。
I notice an usual high memory size. One app i wrote is a console app that uses <50lines and simply downloads a series of files solely using WebRequest. Another app that isnt trivial (mysql, dls, multithreads, listbox with 100 items). The first uses 21 mb (debug, ide), the other uses 39mb(debug, ide). I also have another app polls my site (also using WebRequest) for a status update which sits on my tray and notifies me using 26mbs(release, not ran through ide).
Why are these so high? i know i written a C++ app alike above using curl that ran <2mb and my largest C++ prj is 11mb which loads in a 100kb dll and a 200kb binary (using directx with win32 icons and sound). How can i compile my C# code so its more space friendly. I would like to deploy these to a server which may only have 128 or 256mb ram and a few of these apps would kill it.
Site Note: I ran the first app mentioned (console DLer) in release mode (and through the ide) and it jumped up to 32mb. Why!?! thats more confusing.
发布评论
评论(4)
老实说,不要担心托管代码的占用空间,直到您能够测量其内存大小造成问题的情况。当您启动 .NET 程序集时,CLR 会执行许多不同的操作,此处无法列出,但请参阅 http://weblogs.asp.net/pwilson/archive/2004/02/14/73033.aspx 有关更多资源,请参阅 链接
看一下这篇文章,了解如何确定应用程序实际使用的内存,因为任务管理器不会显示真实的情况 http://www.codinghorror.com/blog/archives/000271.html
如果你真的真的真的想让你的程序集在任务管理器中显示时使用的内存少于放弃托管代码所需的内存。一种作弊方法是使用类似 Salamander Protector 使您的应用程序成为本机可执行文件而不是 .NET 程序集。
Honestly, don't worry about the foot print of managed code until it you are able to measure cases where its memory size is creating issues. There are a lot of different things going on that the CLR does when you launch a .NET assembly, too much to list here, but see http://weblogs.asp.net/pwilson/archive/2004/02/14/73033.aspx and for many more resources see Link
Take a look at this article for some insight on how you can determine what your application is really using on terms of memory because task manager doesn't show the real story http://www.codinghorror.com/blog/archives/000271.html
If you really really really want to make your assembly show in task manager with less memory than you need to ditch managed code. A way to cheat is to compile your application using something like Salamander Protector which makes your application a native executable rather than a .NET assembly.
由于多种原因,小型 .NET 应用程序在内存占用方面无法真正与 C/C++ 应用程序竞争。
与本机应用程序启动所需的运行时相比,.NET 运行时非常庞大。为了运行 .NET 应用程序,CLR 必须位于内存中。它不仅需要加载JIT编译器、GC等组件,还需要许多内部数据结构。例如,即使是最简单的 .NET 应用程序也具有三个 AppDomain,其中两个由 CLR 内部使用,一个用于应用程序本身。
此外,程序集在被引用时会被加载。尽管这些方法在需要时才进行抖动,但程序集本身在加载时会使用大量地址空间。当代码在某个时刻被抖动时,它会再次作为本机代码存储在内存中。因此,基本上已编译的代码在 .NET 应用程序中出现了两次。
最后,与 C/C++ 应用程序中的类型系统相比,.NET 上的类型系统要复杂得多。每个对象都携带有关其类型的信息。这允许反射和其他有用的功能,但它确实是有代价的。
如果您想要非常小的占用空间,.NET 可能就足够了,但它肯定不是最明显的选择,因为您将支付运行时的开销。
另请参阅此相关问题减少 .NET 应用程序的内存使用量?
Small .NET applications can't really compete with C/C++ applications when it comes to memory footprint for a number of reasons.
The .NET runtime is huge compared to what a native app needs for startup. In order to run a .NET app the CLR has to be in memory. Not only will it have to load components such as the JIT compiler, the GC and so forth, it also needs a number of internal data structures. E.g. even the simplest .NET application has three AppDomains, two used internally by the CLR and one for the application itself.
Furthermore assemblies are loaded when they are referred. Even though the methods are not jitted until needed, the assembly itself uses a lot of address space when loaded. When the code is jitted at some point, it is stored once more in memory as native code. So essentially compiled code is present twice in a .NET app.
Finally the type system is a lot more elaborate on .NET compared to what you'll find in a C/C++ app. Every single object carries information about its type. This allows for reflection and other useful features, but it does come at a price.
If you want very small footprint .NET may be good enough, but it certainly isn't the most obvious choice, as you will pay for the overhead of the runtime.
Also, please see this related question Reducing memory usage of .NET applications?
我不是 CLR 方面的专家,但我注意到 CLR 会以块的形式分配内存,并且即使您的应用程序不使用那么多内存,也可能会膨胀得非常高。这有点像 CLR 喜欢保留它不需要的内存,这样它就不需要调用窗口来重新分配。
检查应用程序的私有字节。私有字节应该更合理地指示您实际使用的内存,而不是 CLR 占用的内存量。此外,设置进程的 MaxWorkingSet 似乎可以神奇地重新校准任务管理器中的统计数据。
上面的代码看起来像是 TheDailyWtf 的候选代码。哈哈
I am not an expert on the CLR, but i have noticed that the CLR allocates memory in chunks and can balloon very high even if your application doesn't use that much memory. Its kind of like the CLR likes to hold on to memory which it doesn't need so that it doesn't need to call windows to reallocate.
Check the private bytes of your application. The private bytes should be a more reasonable indicator of the memory your actually using, rather than how much the CLR is holding on to. Also, setting the MaxWorkingSet of the process seems to magically recalibrate the statistics in task manager.
The code above looks like a candidate for TheDailyWtf. LOL
要记住的一件事是,垃圾收集器并不总是释放内存,直到其他东西需要它为止。因此,即使您的应用程序可能声称使用 100MB 内存,但实际上它可能使用 50MB,但垃圾收集器还没有理由收集和释放其余内存。
即使应用程序的基本初始化也会创建大量临时对象,这会导致 CLR 为应用程序分配内存块。只要系统有足够的内存,垃圾收集就会非常懒惰地检测和清理未使用的内存;这是速度优化。不要担心,当您的系统开始需要更多内存时,垃圾收集将会启动并开始进行更深入的扫描。
确保您没有手动调用垃圾收集器,调用的次数越多,就越多的对象被推送到更高的世代,直到系统内存不足时才会被收集。
One of the things to keep in mind is that the garbage collector won't always free memory until something else needs it. So even though your application might claim to be using 100MB of memory, in reality it may be using 50MB but the garbage collector hasn't had a reason to collect and free the rest yet.
Even the basic initialization of an application creates a lot of temporaries, which causes the CLR to allocate memory blocks for the application. As long as the system has plenty of memory the garbage collection will be pretty lazy about detecting and cleaning up the unused memory; this is a speed optimization. Don't fret, when your system starts to need more memory the garbage collection will kick up and start doing deeper scans.
Make sure you aren't manually calling the garbage collector, the more often it is called, the more objects get pushed up in to higher generations that won't be collected until the system is low on memory.