Index: /trunk/src/VBox/Main/MachineImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/MachineImpl.cpp	(revision 30846)
+++ /trunk/src/VBox/Main/MachineImpl.cpp	(revision 30847)
@@ -9597,7 +9597,8 @@
     AutoMultiWriteLock3 multilock(mParent, mParent->host(), this COMMA_LOCKVAL_SRC_POS);
 
-#ifdef VBOX_WITH_RESOURCE_USAGE_API
-    unregisterMetrics(mParent->performanceCollector(), mPeer);
-#endif /* VBOX_WITH_RESOURCE_USAGE_API */
+    // Trigger async cleanup tasks, avoid doing things here which are not
+    // vital to be done immediately and maybe need more locks. This calls
+    // Machine::unregisterMetrics().
+    mParent->onMachineUninit(mPeer);
 
     if (aReason == Uninit::Abnormal)
Index: /trunk/src/VBox/Main/Performance.cpp
===================================================================
--- /trunk/src/VBox/Main/Performance.cpp	(revision 30846)
+++ /trunk/src/VBox/Main/Performance.cpp	(revision 30847)
@@ -120,6 +120,22 @@
 
 #ifndef VBOX_COLLECTOR_TEST_CASE
+
+uint32_t CollectorGuestHAL::cVMsEnabled = 0;
+
+CollectorGuestHAL::CollectorGuestHAL(Machine *machine, CollectorHAL *hostHAL)
+    : CollectorHAL(), cEnabled(0), mMachine(machine), mConsole(NULL),
+      mGuest(NULL), mLastTick(0), mHostHAL(hostHAL), mCpuUser(0),
+      mCpuKernel(0), mCpuIdle(0), mMemTotal(0), mMemFree(0),
+      mMemBalloon(0), mMemShared(0), mMemCache(0), mPageTotal(0)
+{
+    Assert(mMachine);
+    /* cannot use ComObjPtr<Machine> in Performance.h, do it manually */
+    mMachine->AddRef();
+}
+
 CollectorGuestHAL::~CollectorGuestHAL()
 {
+    /* cannot use ComObjPtr<Machine> in Performance.h, do it manually */
+    mMachine->Release();
     Assert(!cEnabled);
 }
@@ -127,8 +143,18 @@
 int CollectorGuestHAL::enable()
 {
+    /* Must make sure that the machine object does not get uninitialized
+     * in the middle of enabling this collector. Causes timing-related
+     * behavior otherwise, which we don't want. In particular the
+     * GetRemoteConsole call below can hang if the VM didn't completely
+     * terminate (the VM processes stop processing events shortly before
+     * closing the session). This avoids the hang. */
+    AutoCaller autoCaller(mMachine);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
     HRESULT ret = S_OK;
 
     if (ASMAtomicIncU32(&cEnabled) == 1)
     {
+        ASMAtomicIncU32(&cVMsEnabled);
         ComPtr<IInternalSessionControl> directControl;
 
@@ -153,4 +179,9 @@
     if (ASMAtomicDecU32(&cEnabled) == 0)
     {
+        if (ASMAtomicDecU32(&cVMsEnabled) == 0)
+        {
+            if (mHostHAL)
+                mHostHAL->setMemHypervisorStats(0 /* ulMemAllocTotal */, 0 /* ulMemFreeTotal */, 0 /* ulMemBalloonTotal */, 0 /* ulMemSharedTotal */);
+        }
         Assert(mGuest && mConsole);
         mGuest->COMSETTER(StatisticsUpdateInterval)(0 /* off */);
Index: /trunk/src/VBox/Main/VirtualBoxImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/VirtualBoxImpl.cpp	(revision 30846)
+++ /trunk/src/VBox/Main/VirtualBoxImpl.cpp	(revision 30847)
@@ -2701,4 +2701,49 @@
 {
     postEvent(new GuestPropertyEvent(this, aMachineId, aName, aValue, aFlags));
+}
+
+/** Event for onMachineUninit(), this is not a CallbackEvent */
+class MachineUninitEvent : public Event
+{
+public:
+
+    MachineUninitEvent(VirtualBox *aVirtualBox, Machine *aMachine)
+        : mVirtualBox(aVirtualBox), mMachine(aMachine)
+    {
+        Assert(aVirtualBox);
+        Assert(aMachine);
+    }
+
+    void *handler()
+    {
+#ifdef VBOX_WITH_RESOURCE_USAGE_API
+        /* Handle unregistering metrics here, as it is not vital to get
+         * it done immediately. It reduces the number of locks needed and
+         * the lock contention in SessionMachine::uninit. */
+        mMachine->unregisterMetrics(mVirtualBox->performanceCollector(), mMachine);
+#endif /* VBOX_WITH_RESOURCE_USAGE_API */
+
+        return NULL;
+    }
+
+private:
+
+    /**
+     *  Note that this is a weak ref -- the CallbackEvent handler thread
+     *  is bound to the lifetime of the VirtualBox instance, so it's safe.
+     */
+    VirtualBox        *mVirtualBox;
+
+    /** Reference to the machine object. */
+    ComObjPtr<Machine> mMachine;
+};
+
+/**
+ *  Trigger internal event. This isn't meant to be signalled to clients.
+ *  @note Doesn't lock any object.
+ */
+void VirtualBox::onMachineUninit(Machine *aMachine)
+{
+    postEvent(new MachineUninitEvent(this, aMachine));
 }
 
Index: /trunk/src/VBox/Main/include/MachineImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/MachineImpl.h	(revision 30846)
+++ /trunk/src/VBox/Main/include/MachineImpl.h	(revision 30847)
@@ -356,4 +356,9 @@
 
     void uninit();
+
+#ifdef VBOX_WITH_RESOURCE_USAGE_API
+    // Needed from VirtualBox, for the delayed metrics cleanup.
+    void unregisterMetrics(PerformanceCollector *aCollector, Machine *aMachine);
+#endif /* VBOX_WITH_RESOURCE_USAGE_API */
 
 protected:
@@ -801,5 +806,4 @@
 #ifdef VBOX_WITH_RESOURCE_USAGE_API
     void registerMetrics(PerformanceCollector *aCollector, Machine *aMachine, RTPROCESS pid);
-    void unregisterMetrics(PerformanceCollector *aCollector, Machine *aMachine);
 
     pm::CollectorGuestHAL  *mGuestHAL;
Index: /trunk/src/VBox/Main/include/Performance.h
===================================================================
--- /trunk/src/VBox/Main/include/Performance.h	(revision 30846)
+++ /trunk/src/VBox/Main/include/Performance.h	(revision 30847)
@@ -186,7 +186,5 @@
     {
     public:
-        CollectorGuestHAL(Machine *machine, CollectorHAL *hostHAL) : CollectorHAL(), cEnabled(0), mMachine(machine), mConsole(NULL), mGuest(NULL),
-                                              mLastTick(0), mHostHAL(hostHAL), mCpuUser(0), mCpuKernel(0), mCpuIdle(0), mMemTotal(0), mMemFree(0),
-                                              mMemBalloon(0), mMemShared(0), mMemCache(0), mPageTotal(0) {};
+        CollectorGuestHAL(Machine *machine, CollectorHAL *hostHAL);
         ~CollectorGuestHAL();
 
@@ -236,4 +234,7 @@
         ULONG                mMemCache;
         ULONG                mPageTotal;
+
+    private:
+        static uint32_t      cVMsEnabled;
     };
 
Index: /trunk/src/VBox/Main/include/VirtualBoxImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/VirtualBoxImpl.h	(revision 30846)
+++ /trunk/src/VBox/Main/include/VirtualBoxImpl.h	(revision 30847)
@@ -215,4 +215,5 @@
     void onGuestPropertyChange(const Guid &aMachineId, IN_BSTR aName, IN_BSTR aValue,
                                IN_BSTR aFlags);
+    void onMachineUninit(Machine *aMachine);
 
     ComObjPtr<GuestOSType> getUnknownOSType();
