我相信许多人已经注意到,当你有一个大的应用程序(即东西需要几MB的DLL),第二次加载比第一次快得多。 如果您在应用程序中读取大文件,则会发生同样的情况。 第一次读后会更快。
什么影响这个? 我想这是硬盘caching,或者是操作系统添加一些自己的内存caching。
您使用什么技术来加速大型应用程序和文件的加载时间?
提前致谢
注意 :这个问题是指Windows
补充:什么影响操作系统的caching大小? 在某些应用程序中,一分钟左右文件再次缓慢加载,所以caching会填满一分钟?
Windows的内存管理器实际上非常漂亮 – 它服务于内存请求,充当磁盘缓存。 在系统上有足够的可用内存的情况下,最近访问过的大量文件将驻留在内存中。 在需要物理内存之前,这些DLL将保留在缓存中 – 全部都是CacheManager。
至于如何帮助,请看延迟加载您的DLL。 LoadLibrary的优点只有当你需要的时候才会自动执行,所以你没有LoadLibrary / GetProcAddress所有的代码。 (自动,只要添加一个链接器命令开关):
http://msdn.microsoft.com/en-us/library/yx9zd12s.aspx
或者你可以像Office和其他人一样预加载(如上所述),但是我个人讨厌这个问题 – 在最初的启动过程中会减慢计算机的速度。
有两件事情可以影响这一点 首先是硬盘缓存(由磁盘完成,影响不大,操作系统往往影响更大)。 第二个是Windows(和其他操作系统)没有什么理由卸载DLL,当他们完成了他们,除非内存是需要的东西。 这是因为DLL可以很容易地在进程之间共享。
所以即使在使用它们的应用程序消失之后,DLL仍然有挂起的习惯。 如果另一个应用程序决定需要DLL,它已经在内存中,只需要映射到进程地址空间。
我已经看到一些应用程序预先加载他们需要的DLL(通常称为QuickStart,我认为MS Office和Adobe Reader都这样做),以便感知加载时间更好。
我看到两种可能性:
我不是那个解决方案的忠实粉丝:它会让你的启动时间更长,并且消耗大量的内存。
例如,为什么在启动时加载一个DLL来导出XYZ格式的文件,当你不确定它会被需要? 当用户选择这种导出格式时加载它。
我有一个梦想,Adobe Acrobat使用这种方法,而不是每次我想显示一个PDF文件时从不使用大量插件的插件!
根据您的需要,您可能需要同时使用这两种技术:预加载一些大的重旧使用的库,并按需加载特定的插件。
一个值得关注的项目是“rebasing”。 每个DLL都有一个预设的“基本”地址,它更喜欢将其加载到内存中。 如果应用程序正在将DLL加载到不同的地址(因为首选项不可用),则DLL将加载到新地址并“重新绑定”。 粗略地说,这意味着dll的一部分被即时更新。 这只适用于本机图像,而不是.NET虚拟机.dll的。
这真的是老的MSDN文章涵盖rebase'ng: http : //msdn.microsoft.com/en-us/library/ms810432.aspx
不知道它是否仍然适用(这是一个非常古老的文章)…但这里是一个诱人的报价:
首选一个大的DLL在几个小的; 确保操作系统不需要很长时间搜索DLL; 并且如果操作系统有可能重新发布DLL(或者,尝试选择基本地址,使得重新绑定不太可能),则避免许多修复。
顺便说一句,如果你处理.NET,那么“ngen'ng”你的应用程序/ dll应该有助于加快速度(ngen = natve图像生成)。
是的,任何从硬盘读入的内容都会被缓存,所以第二次加载的速度会更快。 基本的假设是,从HD只使用一大块数据很少,然后丢弃它(这在实践中通常是一个很好的假设)。 通常情况下,我认为这是实现缓存的操作系统(内核),占用了一大块内存,尽管我不确定现代硬盘是否具有一些内置缓存功能。 (我曾经写过一个小内核作为学术项目,高清数据在内存中的缓存是它的特色之一)
影响程序启动时间的另外一个因素是Superfetch,这是一种与Windows XP相关的技术。 从本质上讲,它监视程序启动时的磁盘访问,识别文件访问模式,并试图“聚合”所需的数据以便快速访问(例如,按照其加载顺序在磁盘上顺序地重新排列数据)。
正如其他人提到的那样,一般而言,任何读操作都可能被Windows磁盘缓存缓存,并被重用,除非内存是其他操作所需要的。
NGENing程序集可能有助于启动时间,但是,运行时可能会受到影响(有时NGEned代码不如OnDemand编译代码最佳)
NGENing也可以在后台完成: http : //blogs.msdn.com/davidnotario/archive/2005/04/27/412838.aspx
这里有另一篇好文章NGen和Performance http://msdn.microsoft.com/en-us/magazine/cc163808.aspx
系统缓存用于任何来自磁盘的内容。 这包括文件元数据,所以如果您使用的应用程序打开大量文件(如目录扫描程序),那么您可以轻松刷新缓存,如果您的应用程序正在运行,则会占用大量内存。
对于我使用的东西,我更喜欢使用少量的大文件(> 64 MB到1 GB)和异步非缓冲I / O。 而且每隔一段时间,一个好的葡萄酒碎片整理。