diff --git a/src/OpenFOAM/db/objectRegistry/objectRegistry.C b/src/OpenFOAM/db/objectRegistry/objectRegistry.C
index fc3c4c8651fc8f49196b63a4f6090b30110e7f64..fe9cdb2a9e4a2ce36cd0ce041126d2158daafe30 100644
--- a/src/OpenFOAM/db/objectRegistry/objectRegistry.C
+++ b/src/OpenFOAM/db/objectRegistry/objectRegistry.C
@@ -333,14 +333,9 @@ bool Foam::objectRegistry::checkOut(const word& key) const
 
 void Foam::objectRegistry::clear()
 {
-    // Free anything owned by the registry
-    // This needs to be done in two stages:
-    // - collect objects-to-be-removed
-    // - actually delete objects
-    // since the destructor of the regIOobject will actually delete its
-    // entry from the objectRegistry which messes up the iterator.
-
-    DynamicList<regIOobject*> owned;
+    // Free anything owned by the registry, but first unset both
+    // 'ownedByRegistry' and 'registered' flags to ensure that the
+    // regIOobject destructor will not affect the registry
 
     for (iterator iter = begin(); iter != end(); ++iter)
     {
@@ -348,26 +343,16 @@ void Foam::objectRegistry::clear()
 
         if (ptr && ptr->ownedByRegistry())
         {
-            // TBD: may wish to have ptr->clearWatches();
             if (objectRegistry::debug)
             {
-                Pout<< "objectRegistry::clear : " << ptr->name()
-                    <<  " watches :" << flatOutput(ptr->watchIndices()) << nl;
-
+                Pout<< "objectRegistry::clear : " << ptr->name() << nl;
             }
 
-            owned.append(ptr);
+            ptr->release(true);     // Relinquish ownership and registration
+            delete ptr;             // Delete also clears fileHandler watches
         }
     }
 
-    for (regIOobject* objectPtr : owned)
-    {
-        // Make sure that the destructor of the regIOobject does a checkout
-        objectPtr->release();
-
-        delete objectPtr;
-    }
-
     HashTable<regIOobject*>::clear();
 }
 
@@ -381,18 +366,18 @@ void Foam::objectRegistry::clearStorage()
 
 bool Foam::objectRegistry::erase(const iterator& iter)
 {
-    // Free anything owned by the registry
+    // Remove from registry - see notes in objectRegistry::clear()
 
     if (iter.found())
     {
         regIOobject* ptr = iter.val();
 
-        bool ok = HashTable<regIOobject*>::erase(iter);
+        const bool ok = HashTable<regIOobject*>::erase(iter);
 
         if (ptr && ptr->ownedByRegistry())
         {
-            // TBD: may wish to have ptr->clearWatches();
-            delete ptr;
+            ptr->release(true);     // Relinquish ownership and registration
+            delete ptr;             // Delete also clears fileHandler watches
         }
 
         return ok;
diff --git a/src/OpenFOAM/db/regIOobject/regIOobject.C b/src/OpenFOAM/db/regIOobject/regIOobject.C
index a933fd799d8c2d5130b420af37d3ab032ac8fbbd..b9abc11951b3378353a9464ea5638ffaeb4ad972 100644
--- a/src/OpenFOAM/db/regIOobject/regIOobject.C
+++ b/src/OpenFOAM/db/regIOobject/regIOobject.C
@@ -156,19 +156,36 @@ Foam::regIOobject::~regIOobject()
 {
     if (objectRegistry::debug)
     {
-        Pout<< "Destroying regIOobject called " << name()
-            << " of type " << type()
-            << " registered " << registered_
-            << " owned " << ownedByRegistry_
-            << " in directory " << path()
+        Pout<< "Destroy regIOobject: " << name()
+            << " type=" << type()
+            << " registered=" << registered_
+            << " owned=" << ownedByRegistry_
+            << " directory=" << path()
             << endl;
     }
 
-    // Check out of objectRegistry if not owned by the registry
-    if (!ownedByRegistry_)
-    {
-        checkOut();
-    }
+    // Deletion of a regIOobject should remove itself from its registry
+    // (ie, checkOut), but there are different paths for destruction to occur.
+    // The complications are only when the object is ownedByRegistry.
+    //
+    // 1. The objectRegistry clear()/erase() is called (and object is
+    //    'ownedByRegistry').
+    //
+    //  - Mark as unowned/unregistered prior to deletion.
+    //    This ensures that this checkOut() only clears file watches and
+    //    does nothing else.
+    //
+    // 2. The regIOobject is deleted directly (and also 'ownedByRegistry').
+    //
+    //  - Mark as unowned (but keep as registered) prior to triggering
+    //    checkOut(). By being 'unowned', the registry will not attempt a
+    //    second deletion when the object name is removed from the registry.
+
+    // Revoke any registry ownership: we are already deleting
+    ownedByRegistry_ = false;
+
+    // Remove registered object from objectRegistry
+    checkOut();
 }
 
 
@@ -212,15 +229,16 @@ bool Foam::regIOobject::checkIn()
 
 bool Foam::regIOobject::checkOut()
 {
+    forAllReverse(watchIndices_, i)
+    {
+        fileHandler().removeWatch(watchIndices_[i]);
+    }
+    watchIndices_.clear();
+
     if (registered_)
     {
         registered_ = false;
 
-        forAllReverse(watchIndices_, i)
-        {
-            fileHandler().removeWatch(watchIndices_[i]);
-        }
-        watchIndices_.clear();
         return db().checkOut(*this);
     }