Safe way to generically allocate memory in Cocoa which will be automatically deallocated - xcode

In my Cocoa project I had a bunch of places where I used malloc/free. However several months ago I decided to refactor to leverage ARC and in order to do that I tried to make a replacement for malloc which will return a pointer to something that will be automatically cleaned up.
I used this function (error checking and other logging omitted)
+ (void *) MallocWithAutoCleanup: (size_t) size
{
NSMutableData * mutableData = [[NSMutableData alloc] initWithLength:size];
void * data = [mutableData mutableBytes];
return data;
}
This worked fine for awhile, but recently a random memory overwrite issue came up. I tracked down the cause to this function, what appears to be happening is the NSMutableData instance is being deallocated even though I am keeping a pointer to its mutableBytes.
I guess this is happening because the only direct reference to the object is local and is going away, and the mutableBytes points inside the object so the ARC isn't smart enough to deal with that sort of reference counting.
Is there any way I can refactor this code to retain the mutableData object as long as the mutableBytes pointer is being used (i.e. someone has a reference to it)? I know one option is to just return the NSMutableData itself, but that requires some heavy refactoring and seems very messy.

In the 10.7 SDK, -[NSMutableData mutableBytes] is decorated with the NS_RETURNS_INNER_POINTER attribute. This signals to the compiler that the method returns a pointer whose validity depends on the receiver still existing. What exactly ARC does with this is open to change, but currently it retains and autoreleases the receiver (subject to redundant operations being optimized away).
So, the pointer is valid for the duration of the current autorelease pool's lifetime. This is akin to -[NSString UTF8String] (which is decorated in the same way).
ARC is not capable of keeping the mutable data object alive so long as there's any reference to the byte pointer. ARC is not a garbage collector. It doesn't watch all uses of all pointers. It operates locally. It examines one given function, method, or block and emits retains and releases for the behavior of the code as indicated by naming conventions. (Remember that ARC is interoperable with code which hasn't been compiled with ARC support.)
Since a void* isn't an object pointer and can't be retained or released, ARC can't do anything with it. So, in the code calling your -MallocWithAutoCleanup: method, ARC doesn't see anything it can manage. It doesn't emit any special memory management code. (What could it emit at that point?) While compiling the caller, the compiler likely doesn't know anything about the method implementation or the mutable data object inside it.
Think about it another way: if you were still writing manually reference counting code, what would you do in the caller of your method to keep the pointer valid? For the most part (ignoring __weak references), all ARC does is automatically do what you would do manually. Once you consider that you would have no options in that case, you realize that neither does ARC.

I think you answered your own question. If you want to use NSData to manage generic memory allocations, you need to keep a reference to the NSData objects around until you're done with the memory it owns, at which point you nil out your reference(s) to the NSData object in question. This doesn't seem to provide any advantage compared to just manually freeing the malloced memory. Personally, I'd continue to use malloc()/free() explicitly instead of trying to contort my code in such a way that ARC kind of sort of manages malloced memory.
Either that, or I'd write my code such that it doesn't have to use malloc/free in the first place. I'd say the typical "pure" Cocoa project doesn't have many, if any, explicit malloc() calls, and I'd be a little suspicious of code that did unless there was some good reason for it. Why are you using malloc() in the first place?

Related

Releasing memory in smart pointer

When we are using dynamically allocated memory, the usefulness of the delete command is obvious - we need to let our program know that the memory at the pointer is no longer needed and can be repurposed.
Smart pointers in C++11 (e.g. unique_ptr) have a member function seemingly used for a similar purpose: release(). I thought the point of using smart pointers was to avoid having to manually handle the release of memory. Why is the release() function provided when, in this context, it seems pointless?
(pun intended)
unique_ptr::release is not equivalent to calling delete on the managed pointer. unique_ptrs are used when you want a sole entity owning a heap-allocated object. unique_ptr::release relinquishes ownership and returns the raw pointer. There might be instances when you no longer want the unique_ptr to own the managed data and yet not destroy the object - maybe you want to call a legacy API which takes a plain pointer and assumes ownership of it. Or perhaps you want your interface receive a unique_ptr but have many shared_ptrs having access to it in the implementation. So, the implementation would release from the unique_ptr and transfer ownership to one or more shared_ptrs.
unique_ptr only automatically releases memory when it goes out of scope or is assigned a new pointer, but you might want to release the memory before that (the most obvious reason would be optimizing memory usage).

Cocoa: Finding the missing reference for deallocating

I'm almost done with and app and I'm using instruments to analyse it. I'm having a problem with ARC deallocating something, but I don't know what. I run instruments using the allocations tool ,what I'm doing is starting the app at the main view, then I mark a heap, I interact with the app a little and return to the original main view and mark another heap.
I do this several times and as I understand it, there should not be any significant heap growth because I am returning to the exact same place, everything I did in between should have been deallocated, providing no heap growth. However I have significant growth so I dive into the heaps and I find that almost everything on it has a retain count of 1, which leads me to believe that one object or view, etc is not being deallocated because of a mistake I've made and that object is what's holding references to everything else.
What I'm trying to find out is which object is not being deallocated. Instruments is very vague and only offers obscure pointers that do not allow me to trace back the problem.
Please let me know if there is a way for me to trace what is holding a reference that may be keeping the retain count at 1.
Thanks.
My 1st thought are 2 things:
1) You may have a retain cycle: As an example, one object has to a delegate a strong reference. And the delegate has also a strong reference (instead of a weak reference) to the 1st object back. Since both of them "hold" the other one, none of them can be released.
2) You may have a multi-threaded app, one of the threads does not have an autorelease pool assigned (i.e. does not have an #autoreleasepool block), and is creating autorelease objects. This may happen even in a simple getter method that returns an autorelease object. If so, the autorelease object is "put" into an non-existing autorelease pool (which does not give you an error message, since you can send any message to nil), and it is never released.
Maybe one of these cases applies to your problem.

What is the design rationale behind HandleScope?

V8 requires a HandleScope to be declared in order to clean up any Local handles that were created within scope. I understand that HandleScope will dereference these handles for garbage collection, but I'm interested in why each Local class doesn't do the dereferencing themselves like most internal ref_ptr type helpers.
My thought is that HandleScope can do it more efficiently by dumping a large number of handles all at once rather than one by one as they would in a ref_ptr type scoped class.
Here is how I understand the documentation and the handles-inl.h source code. I, too, might be completely wrong since I'm not a V8 developer and documentation is scarce.
The garbage collector will, at times, move stuff from one memory location to another and, during one such sweep, also check which objects are still reachable and which are not. In contrast to reference-counting types like std::shared_ptr, this is able to detect and collect cyclic data structures. For all of this to work, V8 has to have a good idea about what objects are reachable.
On the other hand, objects are created and deleted quite a lot during the internals of some computation. You don't want too much overhead for each such operation. The way to achieve this is by creating a stack of handles. Each object listed in that stack is available from some handle in some C++ computation. In addition to this, there are persistent handles, which presumably take more work to set up and which can survive beyond C++ computations.
Having a stack of references requires that you use this in a stack-like way. There is no “invalid” mark in that stack. All the objects from bottom to top of the stack are valid object references. The way to ensure this is the LocalScope. It keeps things hierarchical. With reference counted pointers you can do something like this:
shared_ptr<Object>* f() {
shared_ptr<Object> a(new Object(1));
shared_ptr<Object>* b = new shared_ptr<Object>(new Object(2));
return b;
}
void g() {
shared_ptr<Object> c = *f();
}
Here the object 1 is created first, then the object 2 is created, then the function returns and object 1 is destroyed, then object 2 is destroyed. The key point here is that there is a point in time when object 1 is invalid but object 2 is still valid. That's what LocalScope aims to avoid.
Some other GC implementations examine the C stack and look for pointers they find there. This has a good chance of false positives, since stuff which is in fact data could be misinterpreted as a pointer. For reachability this might seem rather harmless, but when rewriting pointers since you're moving objects, this can be fatal. It has a number of other drawbacks, and relies a lot on how the low level implementation of the language actually works. V8 avoids that by keeping the handle stack separate from the function call stack, while at the same time ensuring that they are sufficiently aligned to guarantee the mentioned hierarchy requirements.
To offer yet another comparison: an object references by just one shared_ptr becomes collectible (and actually will be collected) once its C++ block scope ends. An object referenced by a v8::Handle will become collectible when leaving the nearest enclosing scope which did contain a HandleScope object. So programmers have more control over the granularity of stack operations. In a tight loop where performance is important, it might be useful to maintain just a single HandleScope for the whole computation, so that you won't have to access the handle stack data structure so often. On the other hand, doing so will keep all the objects around for the whole duration of the computation, which would be very bad indeed if this were a loop iterating over many values, since all of them would be kept around till the end. But the programmer has full control, and can arrange things in the most appropriate way.
Personally, I'd make sure to construct a HandleScope
At the beginning of every function which might be called from outside your code. This ensures that your code will clean up after itself.
In the body of every loop which might see more than three or so iterations, so that you only keep variables from the current iteration.
Around every block of code which is followed by some callback invocation, since this ensures that your stuff can get cleaned if the callback requires more memory.
Whenever I feel that something might produce considerable amounts of intermediate data which should get cleaned (or at least become collectible) as soon as possible.
In general I'd not create a HandleScope for every internal function if I can be sure that every other function calling this will already have set up a HandleScope. But that's probably a matter of taste.
Disclaimer: This may not be an official answer, more of a conjuncture on my part; but the v8 documentation is hardly
useful on this topic. So I may be proven wrong.
From my understanding, in developing various v8 based backed application. Its a means of handling the difference between the C++ and javaScript environment.
Imagine the following sequence, which a self dereferencing pointer can break the system.
JavaScript calls up a C++ wrapped v8 function : lets say helloWorld()
C++ function creates a v8::handle of value "hello world =x"
C++ returns the value to the v8 virtual machine
C++ function does its usual cleaning up of resources, including dereferencing of handles
Another C++ function / process, overwrites the freed memory space
V8 reads the handle : and the data is no longer the same "hell!#(#..."
And that's just the surface of the complicated inconsistency between the two; Hence to tackle the various issues of connecting the JavaScript VM (Virtual Machine) to the C++ interfacing code, i believe the development team, decided to simplify the issue via the following...
All variable handles, are to be stored in "buckets" aka HandleScopes, to be built / compiled / run / destroyed by their
respective C++ code, when needed.
Additionally all function handles, are to only refer to C++ static functions (i know this is irritating), which ensures the "existence"
of the function call regardless of constructors / destructor.
Think of it from a development point of view, in which it marks a very strong distinction between the JavaScript VM development team, and the C++ integration team (Chrome dev team?). Allowing both sides to work without interfering one another.
Lastly it could also be the sake of simplicity, to emulate multiple VM : as v8 was originally meant for google chrome. Hence a simple HandleScope creation and destruction whenever we open / close a tab, makes for much easier GC managment, especially in cases where you have many VM running (each tab in chrome).

Check Value of .NET Handle ^

Here's my situation:
I have .NET wrapper-objects in a C++/CLI layer that hold pointers to unmanaged C++ objects. I've implemented the finalizer so that it deletes the unmanaged memory pointed to by the wrapper-object on garbage-collection and sets the pointer to null.
Here's the problem:
I'm watching the finalizer for the .NET wrapper-object and it gets called twice and tries to delete the same memory twice, indicating that I have somehow created 2 .NET wrapper objects that go out-of-scope, and are garbage collected while I'm still expecting the wrapper object to be in scope (these wrapper objects are getting passed to a VB.NET application).
Here's my question:
Is there anyway for me to check the handle value so that I can confirm where the wrapper objects are getting created (copied or whatever)? Currently I'm looking at the handle values (EG - 0x0014fe80), but I see 3 different values for when the object is created, added to a collection, and deleted. So I'm not sure if the GC is just moving stuff around and this is the same object, or if I'm actually seeing 3 different objects that reference the same unmanaged memory. I would like to resolve the duplicate object copies if possible, but I understand that I will probably want to implement some sort of smart pointer so that this doesn't happen.
Thanks,
Ian
Take a look at this question
Here is an implementation of a scoped_ptr that is noncopyable and has an auto-release mechanism for unmanaged objects, by #Ben Voigt
Yeah, I ended up modifying an auto_ptr class to be a shared pointer to ensure that the unmanaged memory is only deleted once through the smart pointer finalizer. I'm assuming I did something similar to all the other implementations; I created a static dictionary in the auto_ptr template class, using the native pointer value as the key, that is checked every time the finalizer is called to update the count of each item, or delete the memory.

In Cocoa do I need to remove an Object from receiving KVO notifications when deallocating it?

When I've registered an object foo to receive KVO notifications from another object bar (using addObserver:...), if I then deallocate foo do I need to send a removeObserver:forKeyPath: message to bar in -dealloc?
You need to use -removeObserver:forKeyPath: to remove the observer before -[NSObject dealloc] runs, so yes, doing it in the -dealloc method of your class would work.
Better than that though would be to have a deterministic point where whatever owns the object that's doing the observing could tell it it's done and will (eventually) be deallocated. That way, you can stop observing immediately when the thing doing the observing is no longer needed, regardless of when it's actually deallocated.
This is important to keep in mind because the lifetime of objects in Cocoa isn't as deterministic as some people seem to think it is. The various Mac OS X frameworks themselves will send your objects -retain and -autorelease, extending their lifetime beyond what you might otherwise think it would be.
Furthermore, when you make the transition to Objective-C garbage collection, you'll find that -finalize will run at very different times — and in very different contexts — than -dealloc did. For one thing, finalization takes place on a different thread, so you really can't safely send -removeObserver:forKeyPath: to another object in a -finalize method.
Stick to memory (and other scarce resource) management in -dealloc and -finalize, and use a separate -invalidate method to have an owner tell an object you're done with it at a deterministic point; do things like removing KVO observations there. The intent of your code will be clearer and you will have fewer subtle bugs to take care of.
A bit of extra info that I've gained by painful experience: although NSNotificationCenter uses zeroing weak references when running under garbage collection, KVO does not. Thus, you can get away with not removing an NSNotificationCenter observer when using GC (when using retain/release, you still need to remove your observer), but you must still remove your KVO observers, as Chris describes.
Definitely agree with Chris on the "Stick to memory (and other scarce resource) management in -dealloc and -finalize..." comment. A lot of times I'll see people try to invalidate NSTimer objects in their dealloc functions. The problem is, NSTimer retains it's targets. So, if the target of that NSTimer is self, dealloc will never get called resulting in some potentially nasty memory leaks.
Invalidate in -invalidate and do other memory cleanup in your dealloc and finalize.

Resources