• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Multiple Undo devours RAM
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Multiple Undo devours RAM


  • Subject: Re: Multiple Undo devours RAM
  • From: Erez Anzel <email@hidden>
  • Date: Wed, 28 Jan 2004 10:05:53 -0500

My thanks to those who answered.

I agree: the last thing that I'd want to do is to mess with memory management by trying to roll my own. I am suggesting that perhaps there's another way, maybe an architectural change to Cocoa, or maybe some guidance for me to avoid this problem.

There are multiple issues here. I will post a separate question on this cocoa-dev list for the notification issue.

UNDO STACK ON DISK: Instead of my large Undo stack entries going into RAM, and then into virtual memory (i.e. disk) when RAM gets tight, I propose the opposite as an option. I realize that this is complicated by the fact that dumping items to a file means that pointers have to be converted into something useful when the information is retrieved. Assuming that the user does not Undo nearly as often as they perform other tasks, I'd say that it's better to use RAM for more common tasks, and write my Undo and Redo stacks directly to disk. The stacks could easily grow to hundreds of megabytes. I'd love to see this as an option in Cocoa; I'm not suggesting that I write it myself.

USING NSZones: Someone suggested that I create my own zones by calling initWithZone. But the bulk of the memory is taken up by the Undo and Redo stacks, and I don't imagine that I can control where they are placed. Am I wrong?

SHRINKING THE UNDO STACK ENTRIES: I agree that it would be useful to shrink my entries. That would mean, for instance, that my action method for moving objects would place the action on the Undo stack, instead of each individual object doing so in its primitive "set" method. I'd have to include the action, its parameter(s), and a list of pointers to the objects. That I could do. But what if the action is something like setting a color? Then I have to store the previous color of each of the selected objects. What if the action changed more than one parameter? Each action has to have its own custom means of posting on entry on the stack.

NOTIFICATION REDUNDANCY: (I'll post this as a separate question later on.) If the user moved 50,000 objects in one action, and I use the "standard" Cocoa approach, then 50,000 notifications are sent to my registered observer(s), each with its own dictionary attached. Three views onto the same data means that each notification is observed and acted upon three times, for a total of 150,000 observations and reactions. Probably pumps up RAM usage as well, since I can't create and release my own pool for these notifications; they have to persist past the time that my action method completes its task. (Again, I'll spin this off into a separate posting.)

VEER FROM COCOA APPROACH: Due to the sheer bulk of objects, messages, etc. which may be involved in each user action, I get the impression that I should use a different approach than we see in the typical samples, Vermont Recipes, etc.

Thanks for any thoughts...Erez


On 27-Jan-04, at 5:46 PM, Public Look wrote:

On Jan 26, 2004, at 8:22 PM, Erez Anzel wrote:

[snip]


I figure that instead of storing the Undo and Redo stacks in memory, as
is currently done, perhaps theres a means of writing them out to disk.
There would be some overhead for each operation, obviously. Perhaps
this could be an option for the user. Or perhaps the hard drive is used
if real RAM starts getting tight, so as to avoid getting bogged down
with virtual memory.

[snip]

In my experience, you should just let the virtual memory system do its thing. It is most likely better at deciding when to transition from RAM storage to disk storage and back, it requires no special programming effort, and it follows the fastest possible I/O bath through the system. The better answer for you is to store your undo data more efficiently.

In a high end CAD like application that my company made, the solution was to treat changes of selection as undo events and only store "operations" with the knowledge that they implicitly apply on the (current) selection. Lots of information gets saved with selection changes, but they are infrequent compared to moves etc.

operation 0: select 500 objects containing 50,000 points
operation 1: move selection 150, -60
operation 2: move selection 0, 1
operation 3: move selection 0, 1
operation 4: select 700 objects
operation 5: set selection color red
operation 6: set selection color blue

As an added bonus, our users liked being able to undo selection changes. It was common for users to accidently select or deselect points due to clutter and sloppiness, but there was no harm done. Just undo :) We also let them save selections in a list with user specified names so they could get back to a favorite selection like "objects in layers 5,6,8 except master points" at any time.

One final trick is to treat objects deletions as just another kind of selection change. The deleted objects are retained in the undo record for the selection change even when removed for the document proper. When the undo record goes away either because of redo or because the user cleared the undo stack, everything gets cleaned up nicely.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.



And from another person:

Let the kernel what it does best- let it handle resource management. However, there is something you can do in order to hint to the kernel that a specific region of memory (some pages) may be less important. Instead of sprawling your inits for the NSDictionaries across your code, try creating your own NSZones for the memory space, call initWithZone: for the undo items that should be globbed together in the same pages. Then, when it comes time to swap, hopefully the older undo items will be paged out automatically.
If you handle the memory management yourself, you are bound to have poor/sporadic/unpredictable performance until you essentially rewrite the kernel's virtual memory management routines. Good luck.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.

  • Follow-Ups:
    • Re: Multiple Undo devours RAM
      • From: Florent Pillet <email@hidden>
References: 
 >Multiple Undo devours RAM (From: Erez Anzel <email@hidden>)
 >Re: Multiple Undo devours RAM (From: Public Look <email@hidden>)

  • Prev by Date: Notification redundancy
  • Next by Date: Re: Adding a people to the system AddressBook
  • Previous by thread: Re: Multiple Undo devours RAM
  • Next by thread: Re: Multiple Undo devours RAM
  • Index(es):
    • Date
    • Thread