Posted by
Peter Caspers-2 on
Apr 01, 2012; 8:13am
URL: http://quantlib.414.s1.nabble.com/QLXL-possible-memory-leak-revisited-tp9438.html
Hi Eric, Ferdinando, Luigi, all,
some months ago there were discussions about a possible memory leak
in QLXL 1.1, in fact I found two related threads
http://old.nabble.com/qlxl-dependencies-and-object-updates-td30925399.html
http://old.nabble.com/possible-memory-leak-in-quantlib-addin-td29510169.html
I guess the reason for the observation of increasing memory usage
when doing recalculations of excel sheets is the multiple
registration of observables on the level of ObjectWrapper in the
object handler. I just inserted a line that unregisters all
observables before registering the precendet objects, i.e.
diff --git
a/ObjectHandler/oh/repository.cpp
b/ObjectHandler/oh/repository.cpp
index 49e8b76..563b4e1 100644
--- a/ObjectHandler/oh/repository.cpp
+++ b/ObjectHandler/oh/repository.cpp
@@ -109,6 +109,8 @@ namespace ObjectHandler {
void Repository::registerObserver(
boost::shared_ptr<ObjectWrapper> objWrapper){
+
objWrapper->unregisterAllWith();
+
const std::set<std::string>& relationObs =
objWrapper->object()->properties()->getPrecedentObjects();
std::set<std::string>::const_iterator iter =
relationObs.begin();
for(; iter != relationObs.end(); iter++){
and thereby fixing the problem as can be tested e.g. in Ferdinandos
test sheet attached to one of the old postings (book2.xls, running
the macro calc_forever).
I think one can also constrain the call of registerObserver to the
case of newly created ObjectWrapper instances and explicitly
overwritten ones, i.e. in addition to the above change one could
write
diff --git
a/ObjectHandler/ohxl/repositoryxl.cpp
b/ObjectHandler/ohxl/repositoryxl.cpp
index 54dbfd0..31e8d9c 100644
--- a/ObjectHandler/ohxl/repositoryxl.cpp
+++ b/ObjectHandler/ohxl/repositoryxl.cpp
@@ -79,6 +79,7 @@ namespace ObjectHandler {
new ObjectWrapperXL(objectID, object,
callingRange));
objectMap_[objectID] = objectWrapperXL;
callingRange->registerObject(objectID,
objectWrapperXL);
+
registerObserver(objectWrapperXL);
} else {
objectWrapperXL =
boost::static_pointer_cast<ObjectWrapperXL>(result->second);
if (objectWrapperXL->callerKey() !=
callingRange->key()) {
@@ -88,11 +89,11 @@ namespace ObjectHandler {
objectWrapperXL->callerAddress());
objectWrapperXL->resetCaller(callingRange);
callingRange->registerObject(objectID,
objectWrapperXL);
+
registerObserver(objectWrapperXL);
}
objectWrapperXL->reset(object);
}
-
- registerObserver(objectWrapperXL);
return objectWrapperXL->idFull();
}
and get the same result with even slightly improved efficiency.
I also noted that the observer / observable pattern code is
duplicated in the object handler (objecthandler/oh/observable.hpp).
In QL 1.2 the storage of observers and observables was changed from
std::list to std::set. I believe that this would also help in the
context above, yet not fully resolve the problem. Anyway, the
improved code should be moved to the object handler, too, yes? Is
there by the way a special reason for duplicating the code? Is it to
keep the object handler independent of QL in some sense?
Thank you
Peter
------------------------------------------------------------------------------
This SF email is sponsosred by:
Try Windows Azure free for 90 days Click Here
http://p.sf.net/sfu/sfd2d-msazure_______________________________________________
QuantLib-dev mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-dev