Something from GPUImageFilters remains in memory even after deallocation - ios

I'm using GPUImage to do a bunch of image processing both in real time and on static images, I noticed that after churning through ~100 thumbnail images each of which has slightly different image processing done to each that there are still objects in memory after they're done processing and they're all related to GPUImageFilters:
(Allocation lifespan is 'created & still living')
You can see the memory spike from some processing I'm doing and after its done, on the other side of the mountain I have some stuff left in memory, I chose some 24KB blocks to examine (there are others). You can see on the right, the first item comes from GPUImageSoftLightBlendFilter, if I click on all 12 items each one comes from a GPUImageFilter (GPUImageHardLightBlendFilter, GPUImageMultiplyBlendFilter, etc). Now if I do the same processing a second time, and expand the memory graph selection you'll see no NEW instances of these objects were made, its as if they took up space in memory once and just hang around:
Sure enough, if I change the memory graph selection to only show the second mountain you see that those line don't show up again because they weren't 'created & still living' again:
Why is this, I don't want the memory from these GPUImageFilter objects hanging around for the lifetime of my app running? I put some logging in the GPUImageFilters to confirm they're being deallocated and dealloc is being called.

From code inspection of the GPUImage source, it looks like the GLProgram object from the last filter used remains set (and retained) by the shared GPUImageContext, which means that its corresponding OpenGL program objects also can't go away. However, the dealloc for the existing GLProgram implementation only marks the current program for deletion. Unlike glDeleteTextures, glDeleteProgram does not unbind the currently-bound program if it's the one being deleted, which means it can't be completely destroyed yet. Therefore, you probably have to make two changes:
Call [GPUImageContext setActiveShaderProgram:nil] to clear the current GLProgram binding, which releases the last reference to GLProgram and marks the current program for deletion.
Ensure that the program is unbound by calling glUseProgram(0). You can either do this any number of ways:
Call it explicitly immediately after the call above, since the correct EAGLContext will already be bound.
Add the call to the body of +[GPUImageContext setActiveShaderProgram:], either by adding it unconditionally above [shaderProgram use], or by calling either [shaderProgram use] or glUseProgram(0) depending on whether shaderProgram is nil.
Have -[GLProgram dealloc] check whether or not it is the currently-bound program with glGetIntegerv(GL_CURRENT_PROGRAM, &program), and unbinding itself if it is.

Related

Does dart reuse memory for previously used instances?

It is hard to find a good heading for this, but i think my problem comes clear if i post a small code snipped:
SomeObject instance = SomeObject(importantParameter);
// -> "instance" is now a reference to the instance somewhere in RAM
instance = SomeObject(anotherImportantParameter);
// -> "instance" is now a reference to a different instance somewhere in RAM
My question is now, is the used RAM that was allocated at the first construction reused at the second construction? Or is the RAM of the first instance marked as unused for the garbage collector and the second construction is done with a completely new instance with a different portion of RAM?
If the first is true, what with this:
while(true) {
final SomeObject instance = SomeObject(importantParameter);
}
Will then, each time the while is repeated, the RAM be reused?
It's unspecified. The answer is a resounding "maybe".
The language specification never says what happens to unreachable objects, since it's unobservable to the program. (That's what being unreachable means).
In practice, the native Dart implementation uses a generational garbage collector.
The default behavior would be to allocate a new object in "new-space" and overwrite the reference to the previous object. That makes the previous object unreachable (as long as you haven't store other references to it), and it can therefore be garbage collected. If you really go through objects quickly, that will be cheap, since the unreachable object is completely ignored on the next new-space garbage collection.
Allocating a lot of short-lived objects still has an overhead since it causes new-space GC to happen more often, even if the individual objects don't themselves cost anything.
There is also a number of optimization that may change this behavior.
If your object is sufficiently simple and the compiler can see that no reference to it ever escapes, or is used in an identical check, or ... any other number of relevant restrictions, then it might "allocation sink" the object. That means it never actually allocates the object, it just stores the contents somewhere, perhaps even on the stack, and it also inlines the methods so they refer to the data directly instead of going through a this pointer.
In that case, your code may actually reuse the memory of the previous object, because the compiler recognizes that it can.
Do not try to predict whether an optimization like this happens. The requirements can change at any time. Just write code that is correct and not unnecessarily complex, then the compiler will do its best to optimize in all the ways that it can.

Is a block in Objective-C always guaranteed to capture a variable?

Are there any conditions in Objective-C (Objective-C++) where the compiler can detect that a variable capture in a block is never used and thus decide to not capture the variable in the first place?
For example, assume you have an NSArray that contains a large number of items which might take a long time to deallocate. You need to access the NSArray on the main thread, but once you're done with it, you're willing to deallocate it on a background queue. The background block only needs to capture the array and then immediately deallocate. It doesn't actually have to do anything with it. Can the compiler detect this and, "erroneously", skip the block capture altogether?
Example:
// On the main thread...
NSArray *outgoingRecords = self.records;
self.records = incomingRecords;
dispatch_async(background_queue, ^{
(void)outgoingRecords;
// After this do-nothing block exits, then outgoingRecords
// should be deallocated on this background_queue.
});
Am I guaranteed that outgoingRecords will always be captured in that block and that it will always be deallocated on the background_queue?
Edit #1
I'll add a bit more context to better illustrate my issue:
I have an Objective-C++ class that contains a very large std::vector of immutable records. This could easily be 1+ million records. They are basic structs in a vector and accessed on the main thread to populate a table view. On a background thread, a different set of database records might be read into a separate vector, which could also be quite large.
Once the background read has occurred, I jump over to the main thread to swap Objective-C objects and repopulate the table.
At that point, I don't care at all about the contents of the older vector or its parent Objective-C class. There's no fancy destructors or object-graph to teardown, but deallocating hundreds of megabytes, maybe even gigabytes of memory is not instantaneous. So I'm willing to punt it off to a background_queue and have the memory deallocation occur there. In my tests, that appears to work fine and gives me a little bit more time on the main thread to do other stuff before 16ms elapses.
I'm trying to understand if I can get away with simply capturing the object in an "empty" block or if I should do some sort of no-op operation (like call count) so that the compiler cannot optimize it away somehow.
Edit #2
(I originally tried to keep the question as simple as possible, but it seems like it's more nuanced then that. Based on Ken's answer below, I'll add another scenario.)
Here's another scenario that doesn't use dispatch_queues but still uses blocks, which is the part I'm really interested in.
id<MTLCommandBuffer> commandBuffer = ...
// A custom class that manages an MTLTexture that is backed by an IOSurface.
__block MyTextureWrapper *wrapper = ...
// Issue some Metal calls that use the texture inside the wrapper.
// Wait for the buffer to complete, then release the wrapper.
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> cb) {
wrapper = nil;
}];
In this scenario, the order of execution is guaranteed by Metal. Unlike the example above, in this scenario performance is not the issue. Rather, the IOSurface that is backing the MTLTexture is being recycled into a CVPixelBufferPool. The IOSurface is being shared between processes and, from what I can tell, MTLTexture does not appear to increase the useCount on the surface. My wrapper class does. When my wrapper class is deallocated, the useCount is decremented and the bufferPool is then free to recycling the IOSurface.
This is all working as expected but I end up with silly code like above just out of uncertainty whether I need to "use" the wrapper instance in the block to ensure it's captured or not. If the wrapper is deallocated before the completion handler runs, then the IOSurface will be recycled and the texture will get overwritten.
Edit to address question edits:
From the Clang Language Specification for Blocks:
Local automatic (stack) variables referenced within the compound
statement of a Block are imported and captured by the Block as const
copies. The capture (binding) is performed at the time of the Block
literal expression evaluation.
The compiler is not required to capture a variable if it can prove
that no references to the variable will actually be evaluated.
Programmers can force a variable to be captured by referencing it in a
statement at the beginning of the Block, like so:
(void) foo;
This matters when capturing the variable has side-effects, as it can
in Objective-C or C++.
(Emphasis added.)
Note that using this technique guarantees that the referenced object lives at least as long as the block, but does not guarantee it will be released with the block, nor by which thread.
There's no guarantee that the block submitted to the background queue will be the last code to hold a strong reference to the array (even ignoring the question of whether the block captures the variable).
First, the block may in fact run before the context which submitted it returns and releases its strong reference. That is, the code which called dispatch_async() could be swapped off the CPU and the block could run first.
But even if the block runs somewhat later than that, a reference to the array may be in an autorelease pool somewhere and not released for some time. Or there may be a strong reference someplace else that will eventually be cleared but not under you explicit control.

Memory leak when accessing GCController's gamepad

I'm adding support for the iOS GameController Framework to a cross-platform input library, and running into some trouble with a memory leak. Here's a simplified version of the troublesome code:
void InputSystem::UpdateControllerState(size_t nControllerIndex)
{
Controller& c = mController[nControllerIndex];
GCController* gc = c.mGameController;
GCExtendedGamepad* gp = [gc extendedGamepad]; // ***
c.mState[kIOSThumbLX] = gp.leftThumbstick.xAxis.value;
c.mState[kIOSThumbLY] = gp.leftThumbstick.yAxis.value;
// ... etc
}
The memory leak seems to be caused by the line marked with ***. I can comment out the lines reading values from the controller and memory is still leaked (under certain circumstances; this could be the key). I have tried adding [gc release] at the end of the function but that doesn’t seem to have any impact. This doesn’t really surprise me since I am not retaining the pointer so I should not need to release it.
The interesting thing is that this code works fine in some conditions. As I was working on the implementation, I set up a basic test that worked just fine. The problem only showed up when I tried hooking up the existing cross-platform unit tests for this library. Here is a bit more detail on the two setups:
(No leak) I set up my InputSystem in applicationDidFinishLaunching,
along with a displayLink to call a function each frame. This
function would call InputSystem code that would call the above
UpdateControllerState method and then print out any new input (button
presses, etc) detected. This setup worked fine; I saw the input from
the controller that I expected, and memory use stayed nice and flat.
(Memory leak) In order to test more rigourously, I hooked in the
cross-platform InputSystem unit tests. These tests include an
interactive mode that continuously loops to poll and print out new
inputs. This doesn’t give iOS the chance to receive input and update
the GCController, so I created a new thread in
applicationDidFinishLaunching to call into the tests. This worked
for getting input, but memory use was steadily increasing. As I
mentioned above, commenting out parts of the new code helped me
narrow it down to the highlighted line above.
I don't understand why these two setups behave differently in this way. Any help understanding this problem would be appreciated. I don't know at this point if this is a problem with how I am using the GCController class, or something I am not understanding about iOS memory in general. Thanks!
EDIT: I just tried storing the pointer to the extendedGamepad in my Controller object, so I could read from it directly and remove the line marked with ***. In this case, however, memory is leaked when I include the lines that read the values from the buttons or thumbsticks.

Debugging strategies for over-retain in ARC?

I've got some objects that are passed to a lot of different views and controllers in my application. They're not getting deallocated when I expect them to. Obviously there is an errant strong pointer somewhere, but the surface area of where it could be is very large--these objects are moved into and out of a lot of different data structures.
My usual go-to solution here is Leaks (which reports no cycles) and Allocations (which lists 500+ retain/releases for this object). Is there any way to reduce my search space here?
Ideally there would be a tool that would let me type in a pointer and see all the strong references to the object, and I could probably eyeball the list and find the extra reference in about 60 seconds. In fact, there is such a tool -- the Object Graph instrument -- but it's not available for iOS software.
You want the Allocations instrument. To track an individual object type, start the application. You need to create a heapshot at every significant event (I usually create them at points when you've just transitioned to or from a view controller).
Once you've got a heapshot that should have the object you're interested in tracking down, then you should be able to find that object type under the heapshot's disclosure triangle. For each object of that type, you can get a history of what retains and releases have been sent to that object by clicking on the arrow in that object's row.
The simplest method to identify whether there is retain cycle or not by just putting a breakpoint in your controller's dealloc()/deinit()(swift) method and whenever you pop your controller check this methods getting called or not if there is retain cycle present in your controller this methods won't get called.
Swift
deinit {
print("Memory to be released soon")
}
Objective C
- (void)dealloc {
NSlog("Memory to be released soon");
}
If you want to get more details about the strong references and root causes you should go with Instrument as the other answer.

Clean JavaFX property listeners and bindings (memory leaks)

I haven't found a simple answer for these two questions:
do I have to remove a listener before deleting the property instance (the listener is not used anywhere else)?
BooleanProperty bool = new SimpleBooleanProperty();
bool.addListener(myListener);
bool.removeListener(myListener); // is it necessary to do this?
bool = null;
do I have to unbind a uni-directional bounded property before deleting the property instance?
BooleanProperty bool = new SimpleBooleanProperty();
bool.bind(otherBool);
bool.unbind(); // is it necessary to do this?
bool = null;
Case 1
Given that myListener "is not used anywhere else" and therefore I assume, a [method-] local variable, the answer is no. In the general case though, the answer is mostly a no but can sometimes be a yes.
As long as myListener is strongly reachable, then it will never become eligible for finalization and it will continue to consume memory. For example, this would be the case if myListener is a "normally" declared static variable (*all "normal" references in Java are strong references*). However, if myListener is a local variable, then the object will not be reachable anymore after the return of the current method call and bool.removeListener(myListener) is a bit meaningless over-engineering. Both the observer and the Observable goes out of scope and will eventually be finalized. A quote from my own blog post about this answer might paint a better picture:
It doesn’t matter if the box know about the cat inside of it, if you
throw the box into the ocean. If the box isn't reachable, nor is the
cat.
Theory
To fully understand the situation here, we have to remind ourselves of the life-cycle of a Java object (source):
An object is strongly reachable if it can be reached by some thread
without traversing any reference objects. A newly-created object is
strongly reachable by the thread that created it. [..] An object is
weakly reachable if it is [not] strongly [..] reachable but can be
reached by traversing a weak reference. When the weak references to a
weakly-reachable object are cleared, the object becomes eligible for
finalization.
In the case of static variables, these will always be accessible as long as the class is loaded, thus reachable. If we didn't want a static reference to be the one that hinder the garbage collector to do his job, then we could declare the variable to use a WeakReference instead. JavaDoc says:
Weak reference objects [..] do not prevent their referents from being
made finalizable, finalized, and then reclaimed. [..] Suppose that the
garbage collector determines at a certain point in time that an object
is weakly reachable. At that time it will atomically clear all weak
references to that object [..]. At the same time it will declare all
of the formerly weakly-reachable objects to be finalizable.
Explicit management
For illustration, let's assume that we write a JavaFX space simulation game. Whenever an Observable planet moves into the view of a spaceship observer, the game engine register the spaceship with the planet. It is quite apparent that whenever the planet goes out of view, the game engine should also remove the spaceship as an observer of the planet by using Observable.removeListener(). Otherwise, as the spaceship continues to fly through space, memory will leak. Eventually, the game cannot handle five billion observed planets and it will crash with an OutOfMemoryError.
Do note that for the vast majority of JavaFX listeners and event handlers, their life-cycle is parallel to that of their Observable so the application developer has nothing to worry about. For example, we might construct a TextField and register with the text field's textProperty a listener that validate user input. As long as the text field sticks around, we want the listener to stick around. Sooner or later, the text field is not used anymore and when he is garbage collected, the validation listener is also garbage collected.
Automatic management
To continue on the space simulation example, assume that our game has limited multiplayer support and all the players need to observe each other. Perhaps each player keep a local score board of kill metrics or perhaps they need to observe broadcasted chat messages. The reason is not the important point here. What would happen when a player quit the game? Clearly, if the listeners are not explicitly managed (removed), then the player who quit will not become eligible for finalization. The other player's will keep a strong reference to the offline player. Explicit removal of the listeners would still be a valid option and probably the most preferred choice for our game, but let's say that it feels a bit obtrusive and we want to find a more slick solution.
We know that the game engine keep strong references to all players online, for as long as they are online. So we want the spaceships to listen for changes or events of each other only for as long as the game engine keep the strong references. If you read the "theory" section, then surely a WeakReference sounds like a solution.
However, just wrapping something in a WeakReference is not the entire solution. It seldom is. It is true that when the last strong reference to the "referent" is set to null or otherwise become unreachable, the referent will be eligible for garbage collection (assuming that the referent cannot be reached using a SoftReference). But the WeakReference is still hanging around. The application developer need to add some plumbing so that the WeakReference itself is removed from the data structure he was put in. If not, then we might have reduced the severity of the memory leak but a memory leak will still be present because dynamically added weak references consume memory too.
Lucky for us, JavaFX added interface WeakListener and class WeakEventHandler as a mechanism for "automatic removal". The constructors of all related classes accept the real listener/handler as provided by client code, but they store the listener/handler using a weak reference.
If you look at the JavaDoc of WeakEventHandler, you'll notice that the class implement EventHandler, so the WeakEventHandler can be used wherever an EventHandler is expected. Likewise, a known implementation of a WeakListener can be used wherever an InvalidationListener or a ChangeListener is expected.
If you look into the source code of WeakEventHandler, you'll notice that the class is basically only a wrapper. When his referent (the real event handler) is garbage collected, the WeakEventHandler "stop working" by not doing anything at all when WeakEventHandler.handle() is called. The WeakEventHandler doesn't know about which object he has been hooked up with, and even if he did, the removal of an event handler is not homogeneous. All known implementing classes of WeakListener has a competitive advantage though. When their callbacks are invoked, they are implicitly or explicitly provided a reference to the Observable they are registered with. So when the referent of a WeakListener is garbage collected, eventually the WeakListener implementation will make sure that the WeakListener itself is removed from the Observable.
If it is isn't already clear, the solution for our space simulation game would be to let the game engine use strong references to all online spaceships. When a spaceship goes online, all other online spaceships are registered with the new player using a weak listener such as WeakInvalidationListener. When a player goes offline, the game engine remove his strong reference to the player and the player will become eligible for garbage collection. The game engine doesn't have to bother about explicit removal of the offline player as a listener of the other players.
Case 2
No. To better understand what I'll say next, please read my case 1 answer first.
BooleanPropertyBase store a strong reference to otherBool. This in itself does not cause otherBool to always be reachable and thus potentially cause a memory leak. When bool becomes unreachable, then so do all its stored references (assuming they are not stored anywhere else).
BooleanPropertyBase also works by adding itself as an Observer of the property you bind it to. However, it does so by wrapping itself in a class that works almost exactly like the WeakListeners described in my case 1 answer. So once you nullify bool, it will be only a matter of time before it is removed from otherBool.
I completely agree with the case 1 answer, but the case 2 is a bit more tricky. The bool.unbind() call is necessary. If ommitted, it does cause a small memory leak.
If you run the following loop, the application will eventually run out of memory.
BooleanProperty p1 = new SimpleBooleanProperty();
while(true) {
BooleanProperty p2 = new SimpleBooleanProperty();
p2.bind(p1)
}
The BooleanPropertyBase, intenally, does not use a real WeakListener (an implementation of the WeakListener interface), it is using a half-baked solution. All the "p2" instances get eventually garbage-collected, but a listener holding an empty WeakReference remains in the memory forever for each "p2". The same holds for all properties, not only BooleanPropertyBase. It's explained here in detail, and they say it is fixed in Java 9.
In most cases, you do not notice this memory leak, because it leaves only a few dozen bytes for every binding that has not been unbound. But in some cases it caused me real trouble. An good example are table cells of a table that gets frequently updated. The cells then re-bind to different properties all the time, and these left-overs in the memory accumulate quickly.

Resources