C# 你能阻止内存被交换到磁盘吗?
我想知道是否有可能防止对象(类或结构)的内存被交换到磁盘 编辑:至于为什么我被告知我将要处理的一些数据无法写入磁盘。C# 你能阻止内存被交换到磁盘吗?,c#,.net,memory,memory-management,C#,.net,Memory,Memory Management,我想知道是否有可能防止对象(类或结构)的内存被交换到磁盘 编辑:至于为什么我被告知我将要处理的一些数据无法写入磁盘。 我不希望它被保留足够长的时间以便交换数据,但我认为它值得检查。您可能正在寻找不会被交换到磁盘的 不太可能,这是操作系统的问题 请放心,Windows的分页策略将优先在内存中保留最频繁访问的页面,因此,如果某个页面对应用程序很重要,它将尽可能多地出现在内存中。嗯,好问题。。您可以在windows中完全禁用交换(size=0),但如果这足以阻止.NET交换,请使用idk。这仅在技术上
我不希望它被保留足够长的时间以便交换数据,但我认为它值得检查。您可能正在寻找不会被交换到磁盘的 不太可能,这是操作系统的问题
请放心,Windows的分页策略将优先在内存中保留最频繁访问的页面,因此,如果某个页面对应用程序很重要,它将尽可能多地出现在内存中。嗯,好问题。。您可以在windows中完全禁用交换(size=0),但如果这足以阻止.NET交换,请使用idk。这仅在技术上可行。可以使用VirtualLock()API函数在RAM中锁定内存页。问题是,这需要提供要锁定的页面的地址。您无法从垃圾收集器以任何有文档记录的方式获取此地址。它也没有承诺,比如说,gen#0堆的相同地址将是可重复的。首先,堆的大小是动态的,通常介于2到8兆字节之间,这取决于程序的分配模式
只是随机地锁定一个大范围,希望你能抓住其中的大部分,这也行不通。进程获得可锁定页面的配额。它不是很大,首先是因为它对机器的运行非常不稳定。龙住在这里。我还不清楚你为什么要这么做。在C#的上下文中,您必须做两件事:“锁定”内存,这样它就不能被垃圾回收重新定位,然后锁定它,这样它就不会被交换出去 下面是一篇很好的博客文章,介绍了如何完成第一部分(固定): 现在需要对象的地址和范围才能调用
VirtualLock
:
请注意,VirtualLock
只锁定页面(单位为4K),因此您的内存区域需要至少有那么大,并且与页面的开头对齐。我假设它需要在不安全的上下文中调用,尽管我不确定
以前关于该主题的帖子:
另一篇相关博文:
我会做一些完全不同的事情:
建立一个好的本地强>包裹C++ +DLL 您希望的函数/分配/任何强< >它也确保数据不被交换>(如这里有人所说的VirtualLock)。从C#开始使用它
毕竟,从本质上讲,这是可能的,只是你现在注定要去C#。所以,绕开它 根据您的环境,您也可以在操作系统级别执行此操作—只需使用一台具有大量RAM的强大机器,并完全禁用分页/交换。这确实意味着您最好永远不要溢出RAM,但这就是任务回到C#的地方-您可以通过智能设计限制最大内存使用量
为什么要阻止这种情况发生?=)你是说除了使用它之外?通常,担心这类事情是由操作系统决定的。只需使用它,您就可以减少将其放置在交换空间中的机会。如果您最近没有使用过它,则可以将其放在磁盘上。你看到经常使用的对象被放在磁盘上了吗?我闻到一种微优化的味道。你怎么知道这对你来说是个问题?@Jens你之所以想这样做是出于安全考虑:例如,如果你不想将密码或密钥保存到磁盘上。(比从RAM中更容易恢复。)我怀疑这是询问者想要的,但感谢链接:)是否有任何参考资料可以证明SecureString不会被交换?我看到它可以被GCed,不被池化,并且被隐式加密。如果SecureString没有被交换,它的实现可能会给出提示。这是不准确的。SecureString的存在是为了避免在分页文件.Hmm中看到该字符串。这可能是一个解决办法,因为原始数据无法存储在磁盘上,但我不确定是否有加密的数据…SecureString会像任何其他托管内存一样交换到磁盘上-但当它这样做时,它是加密的。-为了避免页面文件中的内容,请使用不安全的{}和VirtualLock(),看起来这可能是唯一的方法:(您可能认为ms会提供与VirtualLock相当的.net版本。