3

I have a absolutely huge array (~10 million objects which themselves hold substantial data). Destroying this object causes a quite long lag on the main thread of roughly 5 seconds. While this is just a test case for huge data I'd like to be able to A) better time it's destruction or B) push it off on some background thread to die. I don't know much about the run-time requirement for memory collection but would like a better solution to just spinning for 5 seconds.

So question is how to destroy VERY large objects without facing a long destructor wait on the main thread. I am using ARC and the destructor is being called at a reasonable time (set to nil). Has anyone else dealt with this? Is there a design principle or some other strategy for circumstances like this.

Here is what i'm looking at during profiling

enter image description here

utahwithak
  • 6,235
  • 2
  • 40
  • 62
  • 1
    I assume you could have another "reaper" thread, post your object to it, and unset your own reference. The object should then stay alive til the reaper receives and subsequently forgets it (at which point destruction should happen on the reaper thread). – cHao Aug 18 '14 at 17:52
  • You might want to allocate your objects as a single C array of structs rather than objective-c objects, since deallocating such a C array takes essentially no time. – Jesse Rusak Aug 18 '14 at 17:59
  • Have you tried using an undo stack? You won't have to destroy it. It will be removed when the app is quit. – mikeD Aug 18 '14 at 19:06
  • @cHao Any pointers to how to implement a reaper thread? – utahwithak Aug 18 '14 at 19:10
  • @mikeD That would work but I do want it to go away, just not so noticeably. it is ~1 gig of memory that i'd like to clean out – utahwithak Aug 18 '14 at 19:11
  • @utahwithak: In Cocoa/Objective-C? Not a clue. If i were doing something similar with `shared_ptr`s in C++, i might have a loop that watches a message queue. It wouldn't even have to process the messages; merely retrieving them would update the reference count, and RAII would take care of the rest as soon as the variables went out of scope. I imagine you could do something similar. – cHao Aug 18 '14 at 19:51

1 Answers1

2

I was able to get things working and released on a background thread doing something like:

    __block MyHugeObject* lastResults = self.localHugeObject; //retain it for the block
    self.localHugeObject = nil;//clear local copy

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
        lastResults = nil;//release on a background thread
    });
utahwithak
  • 6,235
  • 2
  • 40
  • 62