Some Matlab versions crash when using listener

4 visualizaciones (últimos 30 días)
Darim
Darim el 4 de Jun. de 2016
Editada: Darim el 6 de Jun. de 2016
Dear Forum,
I've been playing around with listeners in Matlab, i.e. implementation of a weak object reference by using listeners. It appears that my code works fine when using release 2016a or 2015b. It, however, crashes on 2014a, 2015a and 2015a/sp. (Technically it is really not crash but rather a freeze, which does not make a difference to me, since I have to kill the program and restart).
I consider that my implementation is an unfortunate pick and by accident it works with the latest releases of Matlab. I also consider that there is bug. In both cases I kindly ask for a workaround in order to enable my program for any Matlab version.
My code looks like this:
First, the object managed by the weak reference:
classdef ManagedObject < handle
%MANAGEDOBJECT Summary of this class goes here
% Detailed explanation goes here
properties
listenToRuntimeQuery;
end
methods
function setupConnection(obj, weakReference)
% setup listener
for i=1:length(weakReference)
% get weak reference
wRef = weakReference(i);
% get instance of object
cObj = obj(i);
callback = @cObj.getObject;
% create listener connection
obj(i).listenToRuntimeQuery = event.listener(weakReference(i), 'notification',...
@(src, evnt) WeakReference.respond(src, evnt, callback));
end
end
function delete(obj)
% delete listener
delete(obj.listenToRuntimeQuery);
% notify
WeakReference.notifyOnDelete();
end
function obj = getObject(obj)
% Helper callback to request object from weak reference
end
end
end
Second, the implmentation of the weak reference:
classdef WeakReference < handle
%SMARTPOINTER Summary of this class goes here
% Detailed explanation goes here
events
notification;
end
properties
reference;
end
% Constructor
methods
function obj = WeakReference()
end
end
methods
function queryRuntime(obj)
% notify
notify(obj, 'notification');
end
end
methods(Static)
function respond(src, evnt, subject)
%disp('responding');
% store reference temporarily
src.reference = subject();
end
end
methods
function reference = getReference(obj)
% query runtime
obj.queryRuntime();
% return reference
reference = obj.reference();
% clear buffer
obj.reference = [];
end
end
methods (Static)
function notifyOnDelete()
disp('Object has been cleared');
end
end
end
Third, my sample script which will hang on second execution at least in 2014a, 2015a and 2015a/sp1.
% clear all
clear classes
% test settings
N = 10000;
% clear test objects
clear('weakRef')
clear('testObject')
% create object array
testObject(N) = ManagedObject();
% create weak listener
weakRef(N) = WeakReference();
% create smartpointer
testObject.setupConnection(weakRef);
% get reference
for i=1:N
weakRef(i).getReference();
end
Can someone help?
Thanks, Daniel

Respuesta aceptada

Philip Borghesani
Philip Borghesani el 6 de Jun. de 2016
Editada: Philip Borghesani el 6 de Jun. de 2016
MATLAB is not crashing just taking a very long time to complete. Try it with smaller values of N and look how fast the time increases with increases of N. Most of the time is being spent in the destruction sequence called by clear.
You have bumped into a documented weakness in how anonymous functions are implemented in versions prior to R2015b. When an anonymous function is created in older versions of MATLAB all variables in the current workspace are captured by the function.
In your code SetupConnection is causing many many cross links of the full object array and local variables. The solution is to create the listener callback in a separate function:
function setupConnection(obj, weakReference)
% setup listener
for i=1:length(weakReference)
obj(i).listenToRuntimeQuery= event.listener(weakReference(i), 'notification',...
MakeListenerCallback(obj(i)));
end
end
%I placed this function after the end block of the ManagedObject class
function listener=MakeListenerCallback(obj)
getfn=@() obj.getObject;
listener=@(src, evnt) WeakReference.respond(src, evnt, getfn);
end
There are other improvements that can be made to the code. I suggest adding a clear statement to the end of the script and play with any changes observing performance effects using the profiler.

Más respuestas (1)

Darim
Darim el 6 de Jun. de 2016
Editada: Darim el 6 de Jun. de 2016
Philip, thanks a lot for the code snippet and the explanation! This solves my problem and makes things clear now.
Regarding the profiler result, I have to admit that I was happy at the point where my code was running with 2016a. Therefore there are some unneccesary function calls in my example. But anyhow, I think that most of the time is spent at listener construction and notification, which cannot be improved very much. What do you think?

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by