On 1/26/05 10:45 AM, Skip Haughay didst favor us with:
> I have a problem with an application which can potentially attempt to
> allocate memory out to the limits of an application's address space.
> The program presents the user with a spreadsheet-like interface into
> which they may manipulate their data, adding rows and columns as
> necessary. As more elements are added to the data structure, OS X will
> eventually resort to paging. The application gives the user the
> ability to potentially work with 1000 columns of data, with each column
> containing up to a million data points, so you see with the underlying
> data structures to implement this functionality, we are in the
> many-gigabytes range of memory being used by the application.
>
> When we do approach the limits of available memory, both real and
> virtual, an attempt to resize or allocate memory via NewHandle will
> fail. We then go through a strategy that involves unwinding the data
> structures to remove the blocks that we had attempted to add in the
> last user operation.
>
> In this rewind strategy, we had originally traversed the data
> structure, and attempted to resize the underlying blocks of data using
> a SetHandleSize. While these calls returned with no error, an
> examination of the application's memory usage and VM usage indicated
> that these blocks, although being reported smaller at the API level,
> didn't seem to be getting changed in actual size. A fellow software
> engineer on this project did some research and determined that
> apparently OS X does not actually shrink blocks when doing
> SetHandleSize.
You should always tell us what you're doing when you post questions. If you
had told us last time that you were using SetHandleSize to release memory I
would have told you it doesn't actually release memory in Mac OS X. This has
been discussed here in the past, at some length in one thread. But you
didn't say you were using handles or SetHandleSize. I almost asked how you
were allocating and resizing your memory, but I was busy and forgot to.
Sorry about that. Handles in Mac OS X are thin wrappers around malloc, so
the only way to really downside them is to reallocate and move the contents.
Apple's people decided they didn't want the performance hit associated with
that. If you need that kind of memory recovery, you have to do it yourself.
> Anyway we implemented a strategy that tries to allocate
> a new block at the smaller size, copy the data over to it, and then
> purge the former block.
>
> This is all well and good, but we still get into some trouble elsewhere
> in the program when the application memory is low. Specifically, if I
> attempt one of these actions that puts us into a low memory situation,
> and the operation stops and the data structure is wound back to a
> stable state, there is still a possibility that application memory is
> very tight. What happens is that I will do a resize on the window,
> which of course generates an update event. If the window is resized
> just a little bit, no problem. But if it is stretched say all the way
> across a panoramic wide screen display, leaving lots of space in the
> update region, BIG problem. The subsequent redraw attempts to update
> the window, but sometimes (actually quite often) will crash in calls to
> DrawPicture. An examination of the call stack indicates that the issue
> lies somewhere deep within Core Graphics when it finally chokes. Note
> that the picture handles passed to the calls of DrawPicture are fine.
> I examined these, and they refer to valid data, I can see the size is
> proper and the bounding rectangle, etc. It would seem that the problem
> is genuinely that the OS just doesn't have enough to work with to
> update the screen at this point, and whatever DrawPicture is doing
> sends it over the edge.
Mac OS X uses double-buffered windows. That means it needs 32-bits/pixels of
memory for the offscreen buffer of every window, so a 1000x700 pixel window
( a reasonable size on my PowerBook) needs 2.7MB just for its offscreen
buffer.
>
> So what is the strategy here? My questions about this situation are as
> follows:
>
> 1) Is my assessment that this is a low memory behavior that is causing
> Carbon to choke a valid one?
Probably.
> 2) What strategy could we employ to back off on our allocations
> earlier, and still leave the system enough memory in the application
> space to be able to handle UI stuff like updates, and, well, drawing
> pictures.
Not sure what you mean by "strategy" beyond tracking your memory usage,
using it as conservatively as possible, and don't cache any more in memory
more than you absolutely must.
>
> 3) Calls like FreeMem, CompactMem, etc don't seem to work correctly in
> OS X, or have no effect in OS X.
Correct. You aren't in Kansas anymore. ;-)
> Am I right in assuming that these
> calls are essentially meaningless in OS X?
Yes. Memory is never moved in Mac OS X.
> How do I assess how much I
> really have?
I don't remember them, but there are some Unix APIs you can use.
> I can't use grow zone procs to let me know I am getting
> tight. It is all well and good to think that virtual memory is huge
> and more than we will ever need, but then I remember some guy back in
> the 80's saying that 640 K is all we'd ever need, *grin*.
The bottom line is that memory management is way different in Mac OS X and
the old Mac Memory Manager calls are thin wrappers around Unix functions, so
you need to code accordingly.
Larry
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Carbon-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/carbon-dev/email@hidden
This email sent to email@hidden