|
|
1
32
我不会说您应该忽略应用程序的内存占用——显然,更小、更高效的内存占用是可取的。但是,您应该考虑您的实际需求。 如果您正在编写一个标准的Windows窗体和WPF客户机应用程序,这些应用程序将运行在个人的PC上,并且很可能是用户操作的主要应用程序,那么您可以避免在内存分配方面过于懒散。(只要它全部被释放。) 但是,要解决这里的一些人说不要担心的问题:如果您正在编写一个Windows窗体应用程序,它将在终端服务环境中运行,在一个可能由10个、20个或更多用户使用的共享服务器上运行,那么是的,您必须考虑内存使用。你需要保持警惕。解决这一问题的最佳方法是采用良好的数据结构设计,并遵循有关何时以及分配什么内容的最佳实践。 |
|
|
2
44
与本机应用程序相比,.NET应用程序将具有更大的占用空间,因为它们都必须在进程中加载运行时和应用程序。如果你想要真正整洁的东西,.net可能不是最好的选择。 但是,请记住,如果您的应用程序大部分时间处于休眠状态,那么所需的内存页将从内存中交换出来,因此在大多数情况下,这并不是系统的负担。 如果您想保持较小的内存占用,就必须考虑内存使用情况。以下是一些想法:
无论如何,这可能不是一个详尽的清单,而是几个想法。 |
|
|
3
16
在这种情况下,您需要考虑的一件事是clr的内存开销。每个.NET进程都会加载clr,因此会考虑内存因素。对于这样一个简单/小的程序,clr的成本将支配您的内存占用。 与这个基线程序的成本相比,构建一个真正的应用程序并查看它的成本将更有指导意义。 |
|
|
4
7
本身没有具体的建议,但您可以看看
CLR Profiler
(免费从Microsoft下载)。
从操作方法:
|
|
5
6
可能需要查看“真实”应用程序的内存使用情况。 与Java类似,无论程序大小如何,运行时的开销都是固定的,但在那一点之后内存消耗会更合理。 |
|
6
4
还有一些方法可以减少这个简单程序的私有工作集:
|
|
7
2
有很多方法可以减少你的足迹。 有一件事你必须一直生活在 .NET 您的IL代码的本机映像的大小是 巨大的 并且此代码不能在应用程序实例之间完全共享。偶数 NGEN'ed 程序集不是完全静态的,它们还有一些需要抖动的小部件。 人们也倾向于编写比需要的时间长得多的代码来阻塞内存。 一个常见的示例:使用DataReader,将内容加载到数据表中,以便将其写入XML文件。您可以很容易地遇到内存不足的异常。或者,您可以使用一个xmltextwriter,在数据阅读器中滚动,在数据库光标中滚动时发出xmlnodes。 这样,在内存中只有当前的数据库记录及其XML输出。它永远不会(或不太可能)获得更高的垃圾收集生成,因此可以重用。 同样的情况也适用于获取一些实例的列表,做一些事情(产生数千个新实例,这些实例可能在某个地方保持引用),即使之后您不需要它们,但在foreach之后仍然引用所有内容。 显式地将输入列表和临时副产品设为空意味着,即使在退出循环之前,也可以重用此内存。 C有一个称为迭代器的优秀特性。它们允许您通过滚动输入来传输对象,并且只保留当前实例,直到获得下一个实例为止。即使使用LINQ,您仍然不需要仅仅因为希望对其进行过滤就将其保留在周围。 |
|
8
1
解决标题中的一般问题,而不是 具体问题: 如果使用的COM组件返回大量数据 (比如大型2xn双精度数组)只有一小部分 然后可以编写一个包装COM组件, 从.NET中隐藏内存并仅返回 是需要的。 这就是我在主要应用程序中所做的 显著提高了内存消耗。 |
|
|
9
0
我发现,在长时间运行的进程中,使用setprocessworkingsetsize或emptyworkingsetapi强制内存页定期地到磁盘,可能会导致机器上所有可用的物理内存有效地消失,直到机器重新启动。我们将.NET dll加载到本机进程中,该进程将使用EmptyWorkingSet API(替代使用setProcessWorkingSetSize)在执行内存密集型任务后减少工作集。我发现,在1天到一周的时间内,一台机器在任务管理器中显示99%的物理内存使用率,而没有显示任何进程使用任何重要的内存使用率。很快,机器就会失去响应,需要重新启动。说有二十多台Windows Server 2008 R2和2012 R2服务器同时运行在物理和虚拟硬件上。 也许将.NET代码加载到本机进程中与此有关,但使用EmptyWorkingSet(或SetProcessWorkingSetSize)的风险由您自己承担。也许在应用程序初始启动后只使用一次。我决定禁用代码,让垃圾收集器自己管理内存使用情况。 |