diff --git a/src/core/hle/kernel/client_port.h b/src/core/hle/kernel/client_port.h
index 9762bbf0d0..77559ebf9e 100644
--- a/src/core/hle/kernel/client_port.h
+++ b/src/core/hle/kernel/client_port.h
@@ -51,6 +51,8 @@ public:
      */
     void ConnectionClosed();
 
+    void Finalize() override {}
+
 private:
     std::shared_ptr<ServerPort> server_port; ///< ServerPort associated with this client port.
     u32 max_sessions = 0;    ///< Maximum number of simultaneous sessions the port can have
diff --git a/src/core/hle/kernel/client_session.h b/src/core/hle/kernel/client_session.h
index a914c09904..85aafeaf48 100644
--- a/src/core/hle/kernel/client_session.h
+++ b/src/core/hle/kernel/client_session.h
@@ -51,6 +51,8 @@ public:
 
     bool IsSignaled() const override;
 
+    void Finalize() override {}
+
 private:
     static ResultVal<std::shared_ptr<ClientSession>> Create(KernelCore& kernel,
                                                             std::shared_ptr<Session> parent,
diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp
index 10a4e05100..1a2fa9cd83 100644
--- a/src/core/hle/kernel/handle_table.cpp
+++ b/src/core/hle/kernel/handle_table.cpp
@@ -89,6 +89,10 @@ ResultCode HandleTable::Close(Handle handle) {
 
     const u16 slot = GetSlot(handle);
 
+    if (objects[slot].use_count() == 1) {
+        objects[slot]->Finalize();
+    }
+
     objects[slot] = nullptr;
 
     generations[slot] = next_free_slot;
diff --git a/src/core/hle/kernel/k_synchronization_object.cpp b/src/core/hle/kernel/k_synchronization_object.cpp
index 61432fef81..18e7026f57 100644
--- a/src/core/hle/kernel/k_synchronization_object.cpp
+++ b/src/core/hle/kernel/k_synchronization_object.cpp
@@ -136,7 +136,7 @@ ResultCode KSynchronizationObject::Wait(KernelCore& kernel, s32* out_index,
 
 KSynchronizationObject::KSynchronizationObject(KernelCore& kernel) : Object{kernel} {}
 
-KSynchronizationObject ::~KSynchronizationObject() = default;
+KSynchronizationObject::~KSynchronizationObject() = default;
 
 void KSynchronizationObject::NotifyAvailable(ResultCode result) {
     KScopedSchedulerLock lock(kernel);
diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h
index 27124ef677..be7fcb5fb3 100644
--- a/src/core/hle/kernel/object.h
+++ b/src/core/hle/kernel/object.h
@@ -61,6 +61,8 @@ public:
      */
     bool IsWaitable() const;
 
+    virtual void Finalize() = 0;
+
 protected:
     /// The kernel instance this object was created under.
     KernelCore& kernel;
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h
index 5a2cfdb36e..917babfb40 100644
--- a/src/core/hle/kernel/process.h
+++ b/src/core/hle/kernel/process.h
@@ -308,6 +308,8 @@ public:
 
     bool IsSignaled() const override;
 
+    void Finalize() override {}
+
     ///////////////////////////////////////////////////////////////////////////////////////////////
     // Thread-local storage management
 
diff --git a/src/core/hle/kernel/readable_event.h b/src/core/hle/kernel/readable_event.h
index 34e477274a..2195710c20 100644
--- a/src/core/hle/kernel/readable_event.h
+++ b/src/core/hle/kernel/readable_event.h
@@ -47,6 +47,8 @@ public:
 
     bool IsSignaled() const override;
 
+    void Finalize() override {}
+
 private:
     explicit ReadableEvent(KernelCore& kernel);
 
diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h
index 936cc4d0fc..464d4f2a61 100644
--- a/src/core/hle/kernel/resource_limit.h
+++ b/src/core/hle/kernel/resource_limit.h
@@ -85,6 +85,8 @@ public:
      */
     ResultCode SetLimitValue(ResourceType resource, s64 value);
 
+    void Finalize() override {}
+
 private:
     // TODO(Subv): Increment resource limit current values in their respective Kernel::T::Create
     // functions
diff --git a/src/core/hle/kernel/server_port.h b/src/core/hle/kernel/server_port.h
index 6470df993d..29b4f25092 100644
--- a/src/core/hle/kernel/server_port.h
+++ b/src/core/hle/kernel/server_port.h
@@ -81,6 +81,8 @@ public:
 
     bool IsSignaled() const override;
 
+    void Finalize() override {}
+
 private:
     /// ServerSessions waiting to be accepted by the port
     std::vector<std::shared_ptr<ServerSession>> pending_sessions;
diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h
index d45cddec3d..c42d5ee592 100644
--- a/src/core/hle/kernel/server_session.h
+++ b/src/core/hle/kernel/server_session.h
@@ -126,6 +126,8 @@ public:
 
     bool IsSignaled() const override;
 
+    void Finalize() override {}
+
 private:
     /// Queues a sync request from the emulated application.
     ResultCode QueueSyncRequest(std::shared_ptr<KThread> thread, Core::Memory::Memory& memory);
diff --git a/src/core/hle/kernel/session.h b/src/core/hle/kernel/session.h
index f6dd2c1d25..fa3c5651af 100644
--- a/src/core/hle/kernel/session.h
+++ b/src/core/hle/kernel/session.h
@@ -39,6 +39,8 @@ public:
 
     bool IsSignaled() const override;
 
+    void Finalize() override {}
+
     std::shared_ptr<ClientSession> Client() {
         if (auto result{client.lock()}) {
             return result;
diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h
index 0ef87235c8..623bd8b115 100644
--- a/src/core/hle/kernel/shared_memory.h
+++ b/src/core/hle/kernel/shared_memory.h
@@ -71,6 +71,8 @@ public:
         return device_memory.GetPointer(physical_address + offset);
     }
 
+    void Finalize() override {}
+
 private:
     Core::DeviceMemory& device_memory;
     Process* owner_process{};
diff --git a/src/core/hle/kernel/transfer_memory.h b/src/core/hle/kernel/transfer_memory.h
index 05e9f74641..777799d12e 100644
--- a/src/core/hle/kernel/transfer_memory.h
+++ b/src/core/hle/kernel/transfer_memory.h
@@ -72,6 +72,8 @@ public:
     /// is closed.
     ResultCode Reset();
 
+    void Finalize() override {}
+
 private:
     /// The base address for the memory managed by this instance.
     VAddr base_address{};
diff --git a/src/core/hle/kernel/writable_event.cpp b/src/core/hle/kernel/writable_event.cpp
index dbe34472b5..142212ee48 100644
--- a/src/core/hle/kernel/writable_event.cpp
+++ b/src/core/hle/kernel/writable_event.cpp
@@ -38,8 +38,4 @@ void WritableEvent::Clear() {
     readable->Clear();
 }
 
-bool WritableEvent::IsSignaled() const {
-    return readable->IsSignaled();
-}
-
 } // namespace Kernel
diff --git a/src/core/hle/kernel/writable_event.h b/src/core/hle/kernel/writable_event.h
index 6189cf65ce..467eb2c212 100644
--- a/src/core/hle/kernel/writable_event.h
+++ b/src/core/hle/kernel/writable_event.h
@@ -46,7 +46,8 @@ public:
 
     void Signal();
     void Clear();
-    bool IsSignaled() const;
+
+    void Finalize() override {}
 
 private:
     explicit WritableEvent(KernelCore& kernel);