How do I lower the amount of memory IOKit reserves at process start up?
Asked Answered
H

3

11

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).

Herrah answered 27/6, 2011 at 15:48 Comment(0)
C
2

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.

Carnegie answered 3/7, 2011 at 22:57 Comment(8)
A) it is grabbing 512mb of virtual address space, which is based on the size of the frame buffer. B)yes virtual address space. Of which a 32bit application has 4gb. C) Doesn't really answer the question.Herrah
It doesn't matter how many addresses are available, it matters how much memory is available, just because you can count to a number doesn't mean you have that many bits.Carnegie
Ummmm....not sure I understand what you are saying, but it absolutely matters how many addresses are available (32bit vs 64bit). The fact is that 32bit tasks have (roughly) 4GB of virtual address space. Once that is used, memory allocations fail. IOKit is reserving 512mb of virtual address space for the video card framebuffer, and I want to know how to lower that to a smaller amount.Herrah
Why not just compile the application as 64bit? Everything since 10.5 supports it and it bumps your virtual up to 64gig. developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/…Martinsen
compiling as 64bit is not always an option. Quicktime does not support 64bit, for example...Philbrick
I am not sure exactly what you want to do, but altering the system isn't likely to be an answer, you could try using mmap and allocating in essentially a different address space with Physical Address Extension. I will take this moment to reiterate ... you need to do something differently, cache and fetch, or optimize somewhere.Carnegie
I don't really have large number of choices, given the code base I am working with. The 512mb I call out from the framebuffer seems ripe for optimization, given that it seems to stay in the reserved state throughout execution of the application. AND is mapped in every process on the system. With regard to PAE, isn't that kernel level? ie, the OSX kernel already supports it. PAE isn't a user mode technology I can use in my task is it?Herrah
it is a kernel activity, bur i think you can use void * mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset); to essentially make a new page file, then synchronize it, then make a new one. I haven't ever done it, but I think it may be possible.Carnegie
P
0

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<

Philbrick answered 7/7, 2011 at 9:47 Comment(2)
thanks....and yes, 64bit is the long term solution to this issue. Unfortunately, we need to support the 32bit branch of our application for quite some time due to customer needs.Herrah
Also, I have wondered if there was some way to make a low level Out-of-proc memory allocator. By overriding malloc with my own implementation that used IPC to get "memory" from another (64bit) process. Always seemed like a stretch though (not to mention tough to implement in a large legacy codebase).Herrah
S
0

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

Sizar answered 20/7, 2011 at 8:43 Comment(2)
As every OSX application exhibits this behavior, I tried examining processes on other machines, running different video cards. Yes, the amount of memory reserved is different. (it is reserved, but not allocated apparently). I looked for a hardware setting, dug REAL deep into settings, but found nothing that was user settable. After talking to Apple about this issue, it appears to be controlled by the video driver completely. I could hook the call I suppose, but Apple advised against that (obviously).Herrah
Ok.. this is really extreme... but you sound half-competent soSizar

© 2022 - 2024 — McMap. All rights reserved.