到目前为止,我还没有写过一篇博客文章,给出关于做绩效工作的哲学建议。但是最近我想也许是时候写这样一个条目了,因为我见过很多人认真地看一些性能计数器(通常是不正确的)或其他数据,并问了很多问题,比如“这个分配率太高了吗?”,“在我看来它太高了。”或者“我的size太大了,对吧?",在他们没有足够的证据来证明这样的调查和问题是合理的之前,这似乎是个大问题。
现在,如果你只是问些问题来满足你的好奇心,那就太好了。我很乐意回答您的问题,也很乐意为您指出要阅读的文档。但对于那些被要求调查与绩效相关的问题的人,尤其是在期限临近时,我的建议是“在试图找到解决方案之前,先了解问题所在”。根据证据来决定要看什么,而不是基于你对这个领域的知识的缺乏,除非你已经穷尽了你所知道的领域。在你问与GC相关的问题之前,问问你自己你是否认为GC实际上就是问题所在。如果你不能回答这个问题,那么你就不能好好利用你的时间去问与GC相关的问题。
我见过很多例子,当托管应用程序中出现问题时,人们会立即怀疑GC,而没有任何证据支持这种怀疑。然后他们开始问问题——通常是非常随机的——希望他们能在不了解问题是什么的情况下找到解决问题的方法。这不符合逻辑,是吗?所以别这样!

因此,您如何知道要解决的问题是什么,我建议您:

1、了解基础知识真的很有帮助。

什么是基础?一般来说,性能归结为两件事——内存和CPU。了解这两个方面的基本知识有助于确定要看哪一个方面。显然这需要大量的阅读和实验。我将列出一些内存基础知识,以帮助您入门:内存的一些基本原理。

每个进程都有自己独立的虚拟地址空间;同一台机器上的所有进程共享物理内存(如果有页面文件,还可以加上页文件)。在32位上,默认情况下,每个进程都有一个2GB的用户模式虚拟地址空间。
作为应用程序的作者,您使用的是虚拟地址空间—您永远不会直接操作物理内存。如果您正在编写本机代码,您通常通过某种win32堆API(crt堆或进程堆或您创建的堆)使用虚拟地址空间—这些堆API将代表您分配和释放虚拟内存;如果您正在编写托管代码,GC将代表您分配/释放虚拟内存。
虚拟地址空间可能会变得支离破碎-换句话说,地址空间中可能存在“洞”(空闲块)。当请求一个VM分配时,VM管理器需要找到一个足够大的空闲块来满足分配请求-如果只有几个空闲块的总和足够大,它将无法工作。这意味着即使你有2GB,你也不一定看到所有2GB都被使用了。
虚拟机可以处于不同的状态-空闲、保留和提交。免费很容易。有时,人们会困惑于保守和承诺之间的区别。首先,你需要认识到它们是不同的状态。Reserved是说“我想让这个内存区域供我自己使用”。在您保留了一个VM块之后,该块不能用于满足其他保留请求。此时,您还不能将任何数据存储在该内存块中—要做到这一点,您必须提交它,这意味着您必须用一些物理存储来备份数据,以便在其中存储数据。当您通过性能计数器查看内存时,请确保您看到的是正确的。如果要保留的空间或提交的空间不足,则可能会耗尽内存。
如果你有一个页面文件(默认情况下是这样),即使你的物理内存压力很低,你也可以使用它。当你的物理内存压力第一次变大,操作系统需要在物理内存中腾出空间来存储其他数据时,它会在页面文件中备份当前物理内存中的一些数据。在需要数据之前,这些数据不会被分页,这样您就可以进入物理内存负载非常低的情况下观察分页。

2、了解您的性能要求是必须的。

如果你正在编写一个服务器应用程序,很可能你想使用所有可用的内存和CPU,因为人们会完全精巧地使用机器来运行你的应用程序,那么为什么要浪费资源呢?如果你必须在另一台机器上运行的应用程序完全不同,那么你就知道如何在另一台机器上编写故事了。没有“你必须让你的应用程序尽可能少地使用内存”这样的规则。
当你认为有问题的时候,就去挖掘它,而不是去猜测可能出了什么问题。看看是谁在用你的内存。如果您认为托管堆使用了太多内存,请查看原因。使用过多内存的托管堆通常意味着您在应用程序中存活太多对象。看看那些幸存者是怎么活下来的。

标签: none

添加新评论