[Pyobjc-dev] Possible memory leak passing Cocoa NSData or NSDictionary instances from python plugin
Brought to you by:
ronaldoussoren
|
From: Barry W. <bar...@gm...> - 2008-06-02 01:57:21
|
Hi all,
I have an Objective-C application that uses plugins to generate some
data. THe app is compiled against the 10.5 SDK and is running on
Leopard (with the system python and pyobjc). The data is returned as
NSData* instances and its parameters as an NSDictionary instance, as
defined by the app's plugin formal protocol. Some of our plugins are
written in Objective-C and some in Python ("compiled" with py2app).
The app is compiled against the 10.5 SDK and is running on Leopard
(with the system python and pyobjc). I've noticed that there's a
signficant apparent memory leak in the application when using
Python-based plugins, but not when using the Objective-C based
plugins. Therefore, I've concluded that the issue is with the plugins,
not the main application. I've written a small demo app that exhibits
the apparent leak behavior.
The relevant sections of the Objective-C side are:
- (IBAction)getDataFromPython:(id)sender {
id<TestProtocol> plugin = [[pluginClass alloc ] init];
NSAssert([plugin conformsToProtocol:@protocol(TestProtocol)],
@"Plugin not id<TestProtocol>.");
for(NSUInteger i=0; i<self.nReps; i++) {
NSData *d = [plugin getNumpyData];
}
[plugin release];
}
- (IBAction)getDictFromPython:(id)sender {
id<TestProtocol> plugin = [[pluginClass alloc ] init];
NSAssert([plugin conformsToProtocol:@protocol(TestProtocol)],
@"Plugin not id<TestProtocol>.");
for(NSUInteger i=0; i<self.nReps; i++) {
NSDictionary *d = [plugin getDictionary];
}
[plugin release];
}
and the corresponding "getNumpyData" and "getDictFromPython" methods
in the plugin are:
import numpy as np
def getNumpyData(self):
return np.zeros(10000)
def getDictionary(self):
return NSDictionary.dictionaryWithObjectsAndKeys_('abc',
'string',
pkl.dumps(np.zeros(1000)),
'pkl_string',
None)
Investigation with ObjectAlloc in Instruments suggests that the
instances of "GeneralBlock" in the first case (getNumpyData) and
"GeneralBlock" and CFDictionary in the second (getDictionary) case are
created but not released, even after the event loop (and associated
NSAutoreleasePool.drain) are completed.
Is it possible that this is a memory leak caused by improper reference
management across the Objective-C/python bridge?
I am happy to file a bug in Apple's radar or the pyobjc sourceforge
project, but I'm not sure 1) if this is a bug or my fault and 2) where
the bug is most useful...
Would anyone be able to help me?
I've made a zip file with the Xcode project (app and plugin). The
project folder also contains an Instruments file that will drive and
record the behavior I describe above. The zip file is available from
http://rieke-server.physiol.washington.edu/~barry/python/PyObjCTest.zip
Any help would be greatly appreciated!
Thanks!
Barry
|