如何减少进程启动时 IOKit 保留的内存量?
我是一名开发人员,致力于开发一个非常大的内存密集型 32 位应用程序。虚拟地址空间(内存)耗尽对我们来说是一个问题。在调查最近的一些问题时,我注意到 IOKit 保留了一大块内存(512MB)。该内存未被分配,而仅被保留。进一步的调查表明,大多数应用程序(Safari、iTunes 等)也都保留了这块内存。它似乎保持未分配状态。我正在使用 vmmap 进行测试。例如,这是一个使用 XCode 制作的 Cocoa 应用程序,使用默认模板:
REGION TYPE VIRTUAL
=========== =======
CG backing stores 1008K
CG image 4K
CG raster data 64K
CG shared images 2252K
Carbon 7264K
CoreGraphics 16K
IOKit (reserved) 512.0M reserved VM address space (unallocated)
MALLOC 59.0M see MALLOC ZONE table below
MALLOC guard page 48K
MALLOC metadata 348K
Memory tag=242 12K
STACK GUARD 56.0M
Stack 8712K
VM_ALLOCATE 16.2M
__DATA 8296K
__IMAGE 1240K
__LINKEDIT 31.5M
__TEXT 76.7M
__UNICODE 536K
mapped file 27.4M
shared memory 1320K
=========== =======
TOTAL 809.2M
TOTAL, minus reserved VM space 297.2M
我可以做些什么来减少或消除该内存池?我们的应用程序确实可以使用这 512MB!
编辑:我做了一些更多的研究,看来这块内存是映射到用户空间的显卡帧缓冲区。所以我想一个更准确的问题是是否有办法限制帧缓冲区占用这么大一部分用户模式虚拟地址空间?
编辑:做了一些进一步的测试,发现需要更改的关键是 IOFBMemorySize。如果执行此命令,如图所示:
ioreg -l | grep IOFBMemorySize
或者您可以在 IORegistryExplorer 中看到它。但我没能成功改变这个值。我尝试将其添加到 ATIFramebuffer.kext 的 Info.plist 中,但效果不佳。我尝试编写一个调用 IOConnectSetCFProperty 的程序,但它返回 kIOReturnUnsupported。
编辑:经过更多研究,似乎这个 IOFBMemorySize 键可能是只读的,只是报告显卡上的可用内存量。 CoreGraphics 的 Configuration.plist 中似乎有一些有趣的值,但它们似乎都不会影响内存分配(即使在重新启动后)。
I am a developer working on a very large, memory intensive 32bit application. Running out of virtual address space (memory) is a problem for us. During my investigation of some recent issues I noticed a large chunk of memory that is reserved by IOKit (512MB). This memory isn't allocated, but only reserved. Further investigation showed that most applications (Safari, iTunes etc) all reserve this chunk of memory as well. It seems to stay unallocated. I am using vmmap to test. For example, here is a Cocoa application made with XCode, using the default template:
REGION TYPE VIRTUAL
=========== =======
CG backing stores 1008K
CG image 4K
CG raster data 64K
CG shared images 2252K
Carbon 7264K
CoreGraphics 16K
IOKit (reserved) 512.0M reserved VM address space (unallocated)
MALLOC 59.0M see MALLOC ZONE table below
MALLOC guard page 48K
MALLOC metadata 348K
Memory tag=242 12K
STACK GUARD 56.0M
Stack 8712K
VM_ALLOCATE 16.2M
__DATA 8296K
__IMAGE 1240K
__LINKEDIT 31.5M
__TEXT 76.7M
__UNICODE 536K
mapped file 27.4M
shared memory 1320K
=========== =======
TOTAL 809.2M
TOTAL, minus reserved VM space 297.2M
Is there anything I can do to reduce or eliminate that pool of memory? Our application could really use that 512MB!!!
EDIT: I did some more research and it seems that this chunk of memory is the video card framebuffer being mapped into user space. So I guess a more accurate question is if there is anyway to limit framebuffer taking over such a large part of user mode virtual address space?
EDIT: Did some further testing, and found the key that needs to change is IOFBMemorySize. As shown if you do this command:
ioreg -l | grep IOFBMemorySize
Or you can see it in the IORegistryExplorer. I have been unsuccessful in changing that value though. I tried adding it to the Info.plist for the ATIFramebuffer.kext, no good. I tried writing a program that calls IOConnectSetCFProperty, but it returned kIOReturnUnsupported.
EDIT: After more research, seems like this IOFBMemorySize key is likely read only, simply reporting the amount of memory available on the video card. There looked to be some interesting values in the Configuration.plist for CoreGraphics, but none of them seemed to affect the memory allocation (even after a reboot).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为你看待这个问题的方式是错误的。
A) IOKit 没有为帧缓冲区占用 512MB 内存。
B) 它在表中指出您发布了
保留的 VM 地址空间(未分配)
,因此这可能是映射为虚拟内存空间的驱动器内存。C) 如果正在运行的应用程序内存不足,则需要以不同的方式构建它,检查分配和泄漏,并在必要时执行缓存和延迟获取。
I think you are looking at this the wrong way.
A) IOKit is not grabbing up 512MB of memory for a Frame buffer.
B) it states in the table that you posted that
reserved VM address space (unallocated)
so that is probably drive memory that is mapped as a virtual memory space.C) if you are running out of memory in your running application, you need to structure it differently, examine allocs and leaks, and if necessary perform caching and lazy fetching.
诚然,这不是对您问题的答案,而是关于如何继续的建议...
您写道您正在开发一个非常大的 32 位应用程序,所以也许现在是时候重新考虑您的可执行架构并分离将非常大的应用程序分成多个进程。也许您想将 32 位特定(QT?)代码打包到一个应用程序中(无论是后台进程还是 GUI 驱动...),然后将更多内存密集型和面向处理的位放入辅助(64 位?)应用程序中。有多种进程间通信可供选择,您的应用程序可能会受益于更加并行化的架构。
只是一个想法...祝你好运!
|K<
admittedly this is not an answer to your question, but a suggestion on how to continue...
you write that you are working on a very large 32-bit application, so maybe now is the time to re-think your executable architecture and separate the very large application into multiple processes. maybe you want to pack the 32bit specific (QT?) code into one application (be it a background process or GUI driven...) and then put the more memory intensive and processing oriented bits into a secondary (64bit?) application. there are many flavours of inter-process communication to choose from and your app could potentially benefit from a more parallelized architecture.
just an idea... good luck!
|K<
一个。您是否尝试过在较弱的显卡上运行此程序?那么也许只会分配128fb?
显卡的硬件设置?
b.使用代码注入取消内存分配...
假设这是您的私人应用程序,不使用framebuff等
这显然不是单行更改,但是您可以更改代码以分配更小的缓冲区,或者分配失败,或者允许分配然后释放它(并在程序关闭期间反转)等等,
我打赌这可以稳定地进行
a. Have you tried running this on a weaker graphic card? So maybe only 128fb will be allocated?
Hardware settings for the video card?
b. Use code injection to cancel the memory allocation...
Assuming this is your private app, which doesnt use the framebuff, etc,etc
This is obviously not a single line change, but you can change the code to allocate a smaller buffer, or fail the allocation, or allow the allocation and then release it (and reverse this during program shutdown), etc, etc
I bet this can be done in a stable manner