summaryrefslogtreecommitdiff
path: root/cpp/src/IceUtil/GC.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/IceUtil/GC.cpp')
-rw-r--r--cpp/src/IceUtil/GC.cpp28
1 files changed, 15 insertions, 13 deletions
diff --git a/cpp/src/IceUtil/GC.cpp b/cpp/src/IceUtil/GC.cpp
index 148a85fb878..e9fe8052c92 100644
--- a/cpp/src/IceUtil/GC.cpp
+++ b/cpp/src/IceUtil/GC.cpp
@@ -154,10 +154,9 @@ IceUtil::GC::collectGarbage()
ObjectCounts counts;
Time t;
-
GCStats stats;
- RecMutex::Lock sync(*gcRecMutex._m);
+ RecMutex::Lock sync(*gcRecMutex._m); // Prevent any further class reference count activity.
if(_statsCallback)
{
@@ -178,7 +177,6 @@ IceUtil::GC::collectGarbage()
if(_statsCallback)
{
stats.examined = counts.size();
- stats.collected = 0;
}
//
@@ -212,9 +210,9 @@ IceUtil::GC::collectGarbage()
}
}
- for(GCObjectSet::const_iterator k = reachable.begin(); k != reachable.end(); ++k)
+ for(GCObjectSet::const_iterator j = reachable.begin(); j != reachable.end(); ++j)
{
- counts.erase(*k);
+ counts.erase(*j);
}
}
@@ -225,26 +223,30 @@ IceUtil::GC::collectGarbage()
ObjectCounts::const_iterator i;
for(i = counts.begin(); i != counts.end(); ++i)
{
- i->first->__gcClear();
+ i->first->__gcClear(); // Decrement ref count of objects pointed at by this object.
}
for(i = counts.begin(); i != counts.end(); ++i)
{
- gcObjects.erase(i->first);
- delete i->first;
- if(_statsCallback)
- {
- ++stats.collected;
- }
+ gcObjects.erase(i->first); // Remove this object from candidate set.
+ delete i->first; // Delete this object.
}
- counts.clear();
}
if(_statsCallback)
{
stats.msec = (Time::now() - t) * 1000.0L;
+ stats.collected = counts.size();
_statsCallback(stats);
}
+ //
+ // We clear explicitly under protection of the lock, instead of waiting for the
+ // counts destructor. This avoids lots of lock contention later because, otherwise,
+ // the destructor of each object in the counts set would acquire and release
+ // gcRecMutex._m.
+ //
+ counts.clear();
+
{
Monitor<Mutex>::Lock sync(*this);