macos 清除 Mac OS X 上的缓冲区缓存
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/459537/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
clear buffer cache on Mac OS X
提问by Sophie Alpert
Is there a way to programatically clear the buffer cache on the Mac, preferrably in C?
有没有办法以编程方式清除 Mac 上的缓冲区缓存,最好是在 C 中?
Basically, I'm looking for the equivalent of the source of 10.5 (and greater)'s purge
command. EDIT:I now see this is part of the CHUD tools, for which it seems the source isn't directly available. However, I'm still looking for some code to do the same.
基本上,我正在寻找相当于 10.5(及更高版本)purge
命令的源代码。编辑:我现在看到这是 CHUD 工具的一部分,它的源似乎不是直接可用的。但是,我仍在寻找一些代码来做同样的事情。
采纳答案by newgre
I've disassembled the function in question (_utilPurgeDiskBuffers
) from the CHUD framework. The function doesn't seem to be very complex, but since I'm no MacOS programmer, the imports and called sys APIs don't make much sense to me.
我已经_utilPurgeDiskBuffers
从 CHUD 框架中反汇编了有问题的函数 ( )。该函数似乎不是很复杂,但由于我不是 MacOS 程序员,因此导入和调用的 sys API 对我来说没有多大意义。
The first thing the API does is to call another function, namely _miscUtilsUserClientConnect_internal
. This function seems to establish a connection to the CHUD kernel extension.
To do this, it calls _getCHUDUtilsKextService
which tries to locate the CHUD kernel extension by enumerating all kexts using the IORegistryCreateIterator
imported from the I/O kit. After the kext has been found, it is opened via _IOServiceOpen
.
API 所做的第一件事是调用另一个函数,即_miscUtilsUserClientConnect_internal
. 这个函数似乎建立了到 CHUD 内核扩展的连接。
为此,它调用_getCHUDUtilsKextService
which 试图通过使用IORegistryCreateIterator
从 I/O 工具包导入的所有 kext 枚举来定位 CHUD 内核扩展。找到 kext 后,通过_IOServiceOpen
.
At this point we have a connection to the CHUD kext (at least that's my understanding from the disassembly listing).
在这一点上,我们有一个到 CHUD kext 的连接(至少这是我从反汇编列表中的理解)。
Finally a call to IOConnectMethodStructureIStructureO
is made, which I guess carries out the real magic.
Without knowing some internal details or the signature of this function the parameters don't make sense to me.
最后调用IOConnectMethodStructureIStructureO
了,我猜它执行了真正的魔法。
在不知道一些内部细节或这个函数的签名的情况下,这些参数对我来说没有意义。
Here's the disassembly, though:
不过,这是反汇编:
__text:4B0157A7 lea eax, [ebp+var_1C]
__text:4B0157AA mov dword ptr [esp+14h], 0
__text:4B0157B2 mov [esp+10h], eax
__text:4B0157B6 mov [esp+0Ch], eax
__text:4B0157BA mov dword ptr [esp+8], 0
__text:4B0157C2 mov dword ptr [esp+4], 0Eh
__text:4B0157CA mov [esp], edx
__text:4B0157CD call _IOConnectMethodStructureIStr
Note that var_1C
has been zeroed out before.
请注意,var_1C
之前已清零。
Hopefully some of you can make more sense out of those syscalls. If you want more information, let me know.
希望你们中的一些人可以从这些系统调用中获得更多的意义。如果您想了解更多信息,请告诉我。
Update:
To get you started, just take the AppleSamplePCIClient.c
example from the IO kit SDK. This does basically what the purge application from the CHUD tools does.
The only thing you would have to change are the parameters to the final _IOConnectMethodStructureIStr
call. Take them from the disassembly listing above. I cannot test all this stuff since I don't have a Mac.
更新:
为了让您开始,只需AppleSamplePCIClient.c
从 IO 套件 SDK 中获取示例。这基本上完成了 CHUD 工具中的清除应用程序所做的工作。
您唯一需要更改的是最终_IOConnectMethodStructureIStr
调用的参数。从上面的反汇编列表中取出它们。我无法测试所有这些东西,因为我没有 Mac。
回答by lpfavreau
回答by lpfavreau
Wouldn't you be interested in turning off the cache for a file instead? Depending on what you are trying to achieve, it could be an alternative. Good summary here.
您对关闭文件的缓存不感兴趣吗?根据您要实现的目标,它可能是另一种选择。很好的总结在这里。
UBC can be cleared by running 'purge' which allocates a lot of memory to force the cache to clear.
fcntl(fd, F_GLOBAL_NOCACHE, 1)
can be used turn caching off for a particular file. This can be done in any process and the file can be closed after.
UBC 可以通过运行“清除”来清除,它会分配大量内存以强制清除缓存。
fcntl(fd, F_GLOBAL_NOCACHE, 1)
可用于关闭特定文件的缓存。这可以在任何进程中完成,之后可以关闭文件。
回答by Keltia
You could use sync(2)
several times (as in the well-known idiom sync; sync; sync
). I can't seem to find the purge
source code but it may just be part of the man packages available in 10.5.6 code
您可以sync(2)
多次使用(如众所周知的成语sync; sync; sync
)。我似乎找不到purge
源代码,但它可能只是10.5.6 代码中可用的 man 包的一部分
回答by paxdiablo
When you don't have the source code for the tool you wish to emulate (as is the case here), there are a number of ways to go about it.
如果您没有想要模拟的工具的源代码(就像这里的情况),有很多方法可以解决这个问题。
1/ From your C code, simply call the tool with a system()
function call. This works well as long as there's no visible effect (such as opening a graphical window). You could use system("/path/to/purge -purgargs >/dev/null 2>&1");
, for example.
1/ 从您的 C 代码中,只需通过system()
函数调用来调用该工具。只要没有可见效果(例如打开图形窗口),这就会很好地工作。system("/path/to/purge -purgargs >/dev/null 2>&1");
例如,您可以使用。
2/ Reverse-engineer the code to see how it's actually doing it. This is somewhat trickier since it will require knowledge of the assembler language, system calls and many other things.
2/ 对代码进行逆向工程,看看它实际上是如何做的。这有点棘手,因为它需要了解汇编语言、系统调用和许多其他知识。
3/ Contact the developers to obtain tips on how it was done. This doesn't have to be a "send me the code so I can rip it off and make money" question. You could phrase it as "I have an interest in using purge for development but I'm unsure exactly what is does" or "I have security issues with running the code, the powers that be won't let me run it unless we know exactly what it does". Then you code yours to do the same.
3/ 联系开发人员以获取有关如何完成的提示。这不一定是“将代码发送给我,以便我可以窃取并赚钱”的问题。您可以将其表述为“我有兴趣使用清除进行开发,但我不确定到底是做什么的”或“我在运行代码时遇到安全问题,除非我们知道,否则我不会运行它的权力正是它的作用”。然后你编写你的代码来做同样的事情。
Me, I would just use option 1 if possible (I'm inherently lazy :-). If you're going to write a tool to compete with purge (and this'll be hard given it's free), option 2 is probably the best bet.
我,如果可能的话,我只会使用选项 1(我天生很懒:-)。如果您要编写一个与清除竞争的工具(鉴于它是免费的,这将很难),选项 2 可能是最好的选择。