diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp
index 42924a8487..73444d1198 100644
--- a/assignment-client/src/Agent.cpp
+++ b/assignment-client/src/Agent.cpp
@@ -64,6 +64,7 @@ Agent::Agent(ReceivedMessage& message) :
     DependencyManager::get<EntityScriptingInterface>()->setPacketSender(&_entityEditSender);
 
     DependencyManager::set<ResourceManager>();
+    DependencyManager::set<PluginManager>();
 
     DependencyManager::registerInheritance<SpatialParentFinder, AssignmentParentFinder>();
 
@@ -833,6 +834,8 @@ void Agent::aboutToFinish() {
 
     DependencyManager::get<ResourceManager>()->cleanup();
 
+    DependencyManager::destroy<PluginManager>();
+
     // cleanup the AudioInjectorManager (and any still running injectors)
     DependencyManager::destroy<AudioInjectorManager>();
 
diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp
index 34eb138697..d56b22466e 100644
--- a/assignment-client/src/audio/AudioMixer.cpp
+++ b/assignment-client/src/audio/AudioMixer.cpp
@@ -65,7 +65,8 @@ AudioMixer::AudioMixer(ReceivedMessage& message) :
 
     // hash the available codecs (on the mixer)
     _availableCodecs.clear(); // Make sure struct is clean
-    auto codecPlugins = PluginManager::getInstance()->getCodecPlugins();
+    auto pluginManager = DependencyManager::set<PluginManager>();
+    auto codecPlugins = pluginManager->getCodecPlugins();
     std::for_each(codecPlugins.cbegin(), codecPlugins.cend(),
         [&](const CodecPluginPointer& codec) {
             _availableCodecs[codec->getName()] = codec;
@@ -106,6 +107,10 @@ AudioMixer::AudioMixer(ReceivedMessage& message) :
     connect(nodeList.data(), &NodeList::nodeKilled, this, &AudioMixer::handleNodeKilled);
 }
 
+void AudioMixer::aboutToFinish() {
+    DependencyManager::destroy<PluginManager>();
+}
+
 void AudioMixer::queueAudioPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer node) {
     if (message->getType() == PacketType::SilentAudioFrame) {
         _numSilentPackets++;
diff --git a/assignment-client/src/audio/AudioMixer.h b/assignment-client/src/audio/AudioMixer.h
index 8c47893aa3..f9eb18da6d 100644
--- a/assignment-client/src/audio/AudioMixer.h
+++ b/assignment-client/src/audio/AudioMixer.h
@@ -58,6 +58,9 @@ public:
                to.getPublicSocket() != from.getPublicSocket() &&
                to.getLocalSocket() != from.getLocalSocket();
     }
+
+    virtual void aboutToFinish() override;
+    
 public slots:
     void run() override;
     void sendStatsPacket() override;
diff --git a/assignment-client/src/scripts/EntityScriptServer.cpp b/assignment-client/src/scripts/EntityScriptServer.cpp
index eea8e8b470..607ab28b20 100644
--- a/assignment-client/src/scripts/EntityScriptServer.cpp
+++ b/assignment-client/src/scripts/EntityScriptServer.cpp
@@ -58,6 +58,7 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssig
     DependencyManager::get<EntityScriptingInterface>()->setPacketSender(&_entityEditSender);
 
     DependencyManager::set<ResourceManager>();
+    DependencyManager::set<PluginManager>();
 
     DependencyManager::registerInheritance<SpatialParentFinder, AssignmentParentFinder>();
 
@@ -572,6 +573,8 @@ void EntityScriptServer::aboutToFinish() {
 
     DependencyManager::get<ResourceManager>()->cleanup();
 
+    DependencyManager::destroy<PluginManager>();
+
     // cleanup the AudioInjectorManager (and any still running injectors)
     DependencyManager::destroy<AudioInjectorManager>();
     DependencyManager::destroy<ScriptEngines>();
diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp
index 9c262c1980..fb7d6a4a0f 100644
--- a/interface/src/Application.cpp
+++ b/interface/src/Application.cpp
@@ -269,9 +269,6 @@ public:
         }
         _renderContext->doneCurrent();
 
-        // Deleting the object with automatically shutdown the thread
-        connect(qApp, &QCoreApplication::aboutToQuit, this, &QObject::deleteLater);
-
         // Transfer to a new thread
         moveToNewNamedThread(this, "RenderThread", [this](QThread* renderThread) {
             hifi::qt::addBlockingForbiddenThread("Render", renderThread);
@@ -814,6 +811,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
     }
 
     // Tell the plugin manager about our statically linked plugins
+    DependencyManager::set<PluginManager>();
     auto pluginManager = PluginManager::getInstance();
     pluginManager->setInputPluginProvider([] { return getInputPlugins(); });
     pluginManager->setDisplayPluginProvider([] { return getDisplayPlugins(); });
@@ -1378,6 +1376,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
     initializeRenderEngine();
     qCDebug(interfaceapp, "Initialized Render Engine.");
 
+    // Overlays need to exist before we set the ContextOverlayInterface dependency
+    _overlays.init(); // do this before scripts load
+    DependencyManager::set<ContextOverlayInterface>();
+
     // Initialize the user interface and menu system
     // Needs to happen AFTER the render engine initialization to access its configuration
     initializeUi();
@@ -1514,10 +1516,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
     // allow you to move an entity around in your hand
     _entityEditSender.setPacketsPerSecond(3000); // super high!!
 
-    // Overlays need to exist before we set the ContextOverlayInterface dependency
-    _overlays.init(); // do this before scripts load
-    DependencyManager::set<ContextOverlayInterface>();
-
     // Make sure we don't time out during slow operations at startup
     updateHeartbeat();
 
@@ -2555,25 +2553,28 @@ Application::~Application() {
     _octreeProcessor.terminate();
     _entityEditSender.terminate();
 
+    if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) {
+        steamClient->shutdown();
+    }
+    DependencyManager::destroy<PluginManager>();
+
+    DependencyManager::destroy<CompositorHelper>(); // must be destroyed before the FramebufferCache
+
     DependencyManager::destroy<AvatarManager>();
     DependencyManager::destroy<AnimationCache>();
     DependencyManager::destroy<FramebufferCache>();
     DependencyManager::destroy<TextureCache>();
     DependencyManager::destroy<ModelCache>();
-    DependencyManager::destroy<GeometryCache>();
     DependencyManager::destroy<ScriptCache>();
     DependencyManager::destroy<SoundCache>();
     DependencyManager::destroy<OctreeStatsProvider>();
+    DependencyManager::destroy<GeometryCache>();
 
     DependencyManager::get<ResourceManager>()->cleanup();
 
     // remove the NodeList from the DependencyManager
     DependencyManager::destroy<NodeList>();
 
-    if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) {
-        steamClient->shutdown();
-    }
-
 #if 0
     ConnexionClient::getInstance().destroy();
 #endif
@@ -2593,6 +2594,8 @@ Application::~Application() {
 
     // Can't log to file passed this point, FileLogger about to be deleted
     qInstallMessageHandler(LogHandler::verboseMessageHandler);
+    
+    _renderEventHandler->deleteLater();
 }
 
 void Application::initializeGL() {
@@ -2893,6 +2896,7 @@ void Application::initializeUi() {
     auto compositorHelper = DependencyManager::get<CompositorHelper>();
     connect(compositorHelper.data(), &CompositorHelper::allowMouseCaptureChanged, this, [=] {
         if (isHMDMode()) {
+            auto compositorHelper = DependencyManager::get<CompositorHelper>(); // don't capture outer smartpointer
             showCursor(compositorHelper->getAllowMouseCapture() ?
                        Cursor::Manager::lookupIcon(_preferredCursor.get()) :
                        Cursor::Icon::SYSTEM);
diff --git a/interface/src/Application_render.cpp b/interface/src/Application_render.cpp
index 2daa49dcf7..6b4840e3e5 100644
--- a/interface/src/Application_render.cpp
+++ b/interface/src/Application_render.cpp
@@ -139,7 +139,10 @@ void Application::paintGL() {
     frame->frameIndex = _renderFrameCount;
     frame->framebuffer = finalFramebuffer;
     frame->framebufferRecycler = [](const gpu::FramebufferPointer& framebuffer) {
-        DependencyManager::get<FramebufferCache>()->releaseFramebuffer(framebuffer);
+        auto frameBufferCache = DependencyManager::get<FramebufferCache>();
+        if (frameBufferCache) {
+            frameBufferCache->releaseFramebuffer(framebuffer);
+        }
     };
     // deliver final scene rendering commands to the display plugin
     {
diff --git a/libraries/gpu/src/gpu/Frame.cpp b/libraries/gpu/src/gpu/Frame.cpp
index d08a8ab56d..f1001d97d2 100644
--- a/libraries/gpu/src/gpu/Frame.cpp
+++ b/libraries/gpu/src/gpu/Frame.cpp
@@ -21,10 +21,7 @@ Frame::~Frame() {
         framebuffer.reset();
     }
 
-    assert(bufferUpdates.empty());
-    if (!bufferUpdates.empty()) {
-        qFatal("Buffer sync error... frame destroyed without buffer updates being applied");
-    }
+    bufferUpdates.clear();
 }
 
 void Frame::finish() {
diff --git a/libraries/networking/src/ResourceManager.cpp b/libraries/networking/src/ResourceManager.cpp
index 6df15129a2..553f0d0a61 100644
--- a/libraries/networking/src/ResourceManager.cpp
+++ b/libraries/networking/src/ResourceManager.cpp
@@ -39,8 +39,13 @@ ResourceManager::ResourceManager(bool atpSupportEnabled) : _atpSupportEnabled(at
 }
 
 ResourceManager::~ResourceManager() {
-    _thread.terminate();
-    _thread.wait();
+    if (_thread.isRunning()) {
+        _thread.quit();
+        static const auto MAX_RESOURCE_MANAGER_THREAD_QUITTING_TIME = MSECS_PER_SECOND / 2;
+        if (!_thread.wait(MAX_RESOURCE_MANAGER_THREAD_QUITTING_TIME)) {
+            _thread.terminate();
+        }
+    }
 }
 
 void ResourceManager::setUrlPrefixOverride(const QString& prefix, const QString& replacement) {
diff --git a/libraries/plugins/src/plugins/PluginManager.cpp b/libraries/plugins/src/plugins/PluginManager.cpp
index e9c084e132..94ce16cf00 100644
--- a/libraries/plugins/src/plugins/PluginManager.cpp
+++ b/libraries/plugins/src/plugins/PluginManager.cpp
@@ -40,9 +40,8 @@ void PluginManager::setInputPluginSettingsPersister(const InputPluginSettingsPer
     _inputSettingsPersister = persister;
 }
 
-PluginManager* PluginManager::getInstance() {
-    static PluginManager _manager;
-    return &_manager;
+PluginManagerPointer PluginManager::getInstance() {
+    return DependencyManager::get<PluginManager>();
 }
 
 QString getPluginNameFromMetaData(QJsonObject object) {
@@ -136,9 +135,6 @@ const LoaderList& getLoadedPlugins() {
     return loadedPlugins;
 }
 
-PluginManager::PluginManager() {
-}
-
 const CodecPluginList& PluginManager::getCodecPlugins() {
     static CodecPluginList codecPlugins;
     static std::once_flag once;
diff --git a/libraries/plugins/src/plugins/PluginManager.h b/libraries/plugins/src/plugins/PluginManager.h
index f16ad7d09f..65a4012aed 100644
--- a/libraries/plugins/src/plugins/PluginManager.h
+++ b/libraries/plugins/src/plugins/PluginManager.h
@@ -9,12 +9,19 @@
 
 #include <QObject>
 
+#include <DependencyManager.h>
+
 #include "Forward.h"
 
-class PluginManager : public QObject {
+
+class PluginManager;
+using PluginManagerPointer = QSharedPointer<PluginManager>;
+
+class PluginManager : public QObject, public Dependency {
+    SINGLETON_DEPENDENCY
+
 public:
-    static PluginManager* getInstance();
-    PluginManager();
+    static PluginManagerPointer getInstance();
 
     const DisplayPluginList& getDisplayPlugins();
     const InputPluginList& getInputPlugins();
@@ -39,6 +46,8 @@ public:
     void setInputPluginSettingsPersister(const InputPluginSettingsPersister& persister);
     
 private:
+    PluginManager() = default;
+
     DisplayPluginProvider _displayPluginProvider { []()->DisplayPluginList { return {}; } };
     InputPluginProvider _inputPluginProvider { []()->InputPluginList { return {}; } };
     CodecPluginProvider _codecPluginProvider { []()->CodecPluginList { return {}; } };