diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp
index 427c6fc1b8..58c49460f4 100644
--- a/src/core/hle/kernel/handle_table.cpp
+++ b/src/core/hle/kernel/handle_table.cpp
@@ -53,6 +53,7 @@ ResultVal<Handle> HandleTable::Create(Object* obj) {
     switch (obj->GetHandleType()) {
     case HandleType::SharedMemory:
     case HandleType::Thread:
+    case HandleType::Event:
     case HandleType::Process: {
         Handle handle{};
         Add(&handle, reinterpret_cast<KAutoObject*>(obj), {});
diff --git a/src/core/hle/kernel/init/init_slab_setup.cpp b/src/core/hle/kernel/init/init_slab_setup.cpp
index eb9c8e2e44..b292f7db25 100644
--- a/src/core/hle/kernel/init/init_slab_setup.cpp
+++ b/src/core/hle/kernel/init/init_slab_setup.cpp
@@ -9,6 +9,7 @@
 #include "core/core.h"
 #include "core/hardware_properties.h"
 #include "core/hle/kernel/init/init_slab_setup.h"
+#include "core/hle/kernel/k_event.h"
 #include "core/hle/kernel/k_memory_layout.h"
 #include "core/hle/kernel/k_memory_manager.h"
 #include "core/hle/kernel/k_shared_memory.h"
@@ -25,6 +26,7 @@ namespace Kernel::Init {
 #define FOREACH_SLAB_TYPE(HANDLER, ...)                                                            \
     HANDLER(Process, (SLAB_COUNT(Process)), ##__VA_ARGS__)                                         \
     HANDLER(KThread, (SLAB_COUNT(KThread)), ##__VA_ARGS__)                                         \
+    HANDLER(KEvent, (SLAB_COUNT(KEvent)), ##__VA_ARGS__)                                           \
     HANDLER(KSharedMemory, (SLAB_COUNT(KSharedMemory)), ##__VA_ARGS__)
 
 namespace {
diff --git a/src/core/hle/kernel/k_event.cpp b/src/core/hle/kernel/k_event.cpp
index bb2fa4ad56..bc4a79cc84 100644
--- a/src/core/hle/kernel/k_event.cpp
+++ b/src/core/hle/kernel/k_event.cpp
@@ -4,29 +4,53 @@
 
 #include "core/hle/kernel/k_event.h"
 #include "core/hle/kernel/k_readable_event.h"
+#include "core/hle/kernel/k_resource_limit.h"
 #include "core/hle/kernel/k_writable_event.h"
+#include "core/hle/kernel/process.h"
 
 namespace Kernel {
 
-KEvent::KEvent(KernelCore& kernel, std::string&& name) : Object{kernel, std::move(name)} {}
+KEvent::KEvent(KernelCore& kernel) : KAutoObjectWithSlabHeapAndContainer{kernel} {}
 
 KEvent::~KEvent() = default;
 
-std::shared_ptr<KEvent> KEvent::Create(KernelCore& kernel, std::string&& name) {
-    return std::make_shared<KEvent>(kernel, std::move(name));
-}
+void KEvent::Initialize(std::string&& name_) {
+    // Increment reference count.
+    // Because reference count is one on creation, this will result
+    // in a reference count of two. Thus, when both readable and
+    // writable events are closed this object will be destroyed.
+    Open();
 
-void KEvent::Initialize() {
     // Create our sub events.
-    readable_event = std::make_shared<KReadableEvent>(kernel, GetName() + ":Readable");
-    writable_event = std::make_shared<KWritableEvent>(kernel, GetName() + ":Writable");
+    readable_event = std::make_shared<KReadableEvent>(kernel, name_ + ":Readable");
+    writable_event = std::make_shared<KWritableEvent>(kernel, name_ + ":Writable");
 
     // Initialize our sub sessions.
     readable_event->Initialize(this);
     writable_event->Initialize(this);
 
+    // Set our owner process.
+    owner = kernel.CurrentProcess();
+    if (owner) {
+        owner->Open();
+    }
+
     // Mark initialized.
+    name = std::move(name_);
     initialized = true;
 }
 
+void KEvent::Finalize() {
+    KAutoObjectWithSlabHeapAndContainer<KEvent, KAutoObjectWithList>::Finalize();
+}
+
+void KEvent::PostDestroy(uintptr_t arg) {
+    // Release the event count resource the owner process holds.
+    Process* owner = reinterpret_cast<Process*>(arg);
+    if (owner) {
+        owner->GetResourceLimit()->Release(LimitableResource::Events, 1);
+        owner->Close();
+    }
+}
+
 } // namespace Kernel
diff --git a/src/core/hle/kernel/k_event.h b/src/core/hle/kernel/k_event.h
index ec6894b16a..97ec0ea9c7 100644
--- a/src/core/hle/kernel/k_event.h
+++ b/src/core/hle/kernel/k_event.h
@@ -4,24 +4,34 @@
 
 #pragma once
 
-#include "core/hle/kernel/object.h"
+#include "core/hle/kernel/slab_helpers.h"
 
 namespace Kernel {
 
 class KernelCore;
 class KReadableEvent;
 class KWritableEvent;
+class Process;
+
+class KEvent final : public KAutoObjectWithSlabHeapAndContainer<KEvent, KAutoObjectWithList> {
+    KERNEL_AUTOOBJECT_TRAITS(KEvent, KAutoObject);
 
-class KEvent final : public Object {
 public:
-    explicit KEvent(KernelCore& kernel, std::string&& name);
+    explicit KEvent(KernelCore& kernel);
     ~KEvent() override;
 
-    static std::shared_ptr<KEvent> Create(KernelCore& kernel, std::string&& name);
+    void Initialize(std::string&& name);
 
-    void Initialize();
+    virtual void Finalize() override;
 
-    void Finalize() override {}
+    virtual bool IsInitialized() const override {
+        return initialized;
+    }
+    virtual uintptr_t GetPostDestroyArgument() const override {
+        return reinterpret_cast<uintptr_t>(owner);
+    }
+
+    static void PostDestroy(uintptr_t arg);
 
     std::string GetTypeName() const override {
         return "KEvent";
@@ -51,6 +61,7 @@ public:
 private:
     std::shared_ptr<KReadableEvent> readable_event;
     std::shared_ptr<KWritableEvent> writable_event;
+    Process* owner{};
     bool initialized{};
 };
 
diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h
index 5c14aa46f9..03443b947b 100644
--- a/src/core/hle/kernel/object.h
+++ b/src/core/hle/kernel/object.h
@@ -71,6 +71,8 @@ protected:
 
 private:
     std::atomic<u32> object_id{0};
+
+protected:
     std::string name;
 };
 
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 17d63658a5..b143a51c7d 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -1953,14 +1953,11 @@ static ResultCode CreateEvent(Core::System& system, Handle* out_write, Handle* o
     HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable();
 
     // Create a new event.
-    const auto event = KEvent::Create(kernel, "CreateEvent");
-    if (!event) {
-        LOG_ERROR(Kernel_SVC, "Unable to create new events. Event creation limit reached.");
-        return ResultOutOfResource;
-    }
+    KEvent* event = KEvent::CreateWithKernel(kernel);
+    R_UNLESS(event != nullptr, ResultOutOfResource);
 
     // Initialize the event.
-    event->Initialize();
+    event->Initialize("CreateEvent");
 
     // Add the writable event to the handle table.
     const auto write_create_result = handle_table.Create(event->GetWritableEvent().get());
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 7be94446a7..3800c65ade 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -253,7 +253,8 @@ IDebugFunctions::IDebugFunctions(Core::System& system_)
 IDebugFunctions::~IDebugFunctions() = default;
 
 ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nvflinger_)
-    : ServiceFramework{system_, "ISelfController"}, nvflinger{nvflinger_} {
+    : ServiceFramework{system_, "ISelfController"}, nvflinger{nvflinger_},
+      launchable_event{system.Kernel()}, accumulated_suspended_tick_changed_event{system.Kernel()} {
     // clang-format off
     static const FunctionInfo functions[] = {
         {0, &ISelfController::Exit, "Exit"},
@@ -306,19 +307,17 @@ ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nv
 
     RegisterHandlers(functions);
 
-    auto& kernel = system.Kernel();
-    launchable_event = Kernel::KEvent::Create(kernel, "ISelfController:LaunchableEvent");
-    launchable_event->Initialize();
+    launchable_event.Initialize("ISelfController:LaunchableEvent");
 
     // This event is created by AM on the first time GetAccumulatedSuspendedTickChangedEvent() is
     // called. Yuzu can just create it unconditionally, since it doesn't need to support multiple
     // ISelfControllers. The event is signaled on creation, and on transition from suspended -> not
     // suspended if the event has previously been created by a call to
     // GetAccumulatedSuspendedTickChangedEvent.
-    accumulated_suspended_tick_changed_event =
-        Kernel::KEvent::Create(kernel, "ISelfController:AccumulatedSuspendedTickChangedEvent");
-    accumulated_suspended_tick_changed_event->Initialize();
-    accumulated_suspended_tick_changed_event->GetWritableEvent()->Signal();
+
+    accumulated_suspended_tick_changed_event.Initialize(
+        "ISelfController:AccumulatedSuspendedTickChangedEvent");
+    accumulated_suspended_tick_changed_event.GetWritableEvent()->Signal();
 }
 
 ISelfController::~ISelfController() = default;
@@ -377,11 +376,11 @@ void ISelfController::LeaveFatalSection(Kernel::HLERequestContext& ctx) {
 void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) {
     LOG_WARNING(Service_AM, "(STUBBED) called");
 
-    launchable_event->GetWritableEvent()->Signal();
+    launchable_event.GetWritableEvent()->Signal();
 
     IPC::ResponseBuilder rb{ctx, 2, 1};
     rb.Push(RESULT_SUCCESS);
-    rb.PushCopyObjects(launchable_event->GetReadableEvent());
+    rb.PushCopyObjects(launchable_event.GetReadableEvent());
 }
 
 void ISelfController::SetScreenShotPermission(Kernel::HLERequestContext& ctx) {
@@ -560,7 +559,7 @@ void ISelfController::GetAccumulatedSuspendedTickChangedEvent(Kernel::HLERequest
 
     IPC::ResponseBuilder rb{ctx, 2, 1};
     rb.Push(RESULT_SUCCESS);
-    rb.PushCopyObjects(accumulated_suspended_tick_changed_event->GetReadableEvent());
+    rb.PushCopyObjects(accumulated_suspended_tick_changed_event.GetReadableEvent());
 }
 
 void ISelfController::SetAlbumImageTakenNotificationEnabled(Kernel::HLERequestContext& ctx) {
@@ -578,38 +577,36 @@ void ISelfController::SetAlbumImageTakenNotificationEnabled(Kernel::HLERequestCo
     rb.Push(RESULT_SUCCESS);
 }
 
-AppletMessageQueue::AppletMessageQueue(Kernel::KernelCore& kernel) {
-    on_new_message = Kernel::KEvent::Create(kernel, "AMMessageQueue:OnMessageReceived");
-    on_new_message->Initialize();
-    on_operation_mode_changed =
-        Kernel::KEvent::Create(kernel, "AMMessageQueue:OperationModeChanged");
-    on_operation_mode_changed->Initialize();
+AppletMessageQueue::AppletMessageQueue(Kernel::KernelCore& kernel)
+    : on_new_message{kernel}, on_operation_mode_changed{kernel} {
+    on_new_message.Initialize("AMMessageQueue:OnMessageReceived");
+    on_operation_mode_changed.Initialize("AMMessageQueue:OperationModeChanged");
 }
 
 AppletMessageQueue::~AppletMessageQueue() = default;
 
 Kernel::KReadableEvent* AppletMessageQueue::GetMessageReceiveEvent() const {
-    return on_new_message->GetReadableEvent();
+    return on_new_message.GetReadableEvent().get();
 }
 
 Kernel::KReadableEvent* AppletMessageQueue::GetOperationModeChangedEvent() const {
-    return on_operation_mode_changed->GetReadableEvent();
+    return on_operation_mode_changed.GetReadableEvent().get();
 }
 
 void AppletMessageQueue::PushMessage(AppletMessage msg) {
     messages.push(msg);
-    on_new_message->GetWritableEvent()->Signal();
+    on_new_message.GetWritableEvent()->Signal();
 }
 
 AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() {
     if (messages.empty()) {
-        on_new_message->GetWritableEvent()->Clear();
+        on_new_message.GetWritableEvent()->Clear();
         return AppletMessage::NoMessage;
     }
     auto msg = messages.front();
     messages.pop();
     if (messages.empty()) {
-        on_new_message->GetWritableEvent()->Clear();
+        on_new_message.GetWritableEvent()->Clear();
     }
     return msg;
 }
@@ -629,7 +626,7 @@ void AppletMessageQueue::FocusStateChanged() {
 void AppletMessageQueue::OperationModeChanged() {
     PushMessage(AppletMessage::OperationModeChanged);
     PushMessage(AppletMessage::PerformanceModeChanged);
-    on_operation_mode_changed->GetWritableEvent()->Signal();
+    on_operation_mode_changed.GetWritableEvent()->Signal();
 }
 
 ICommonStateGetter::ICommonStateGetter(Core::System& system_,
@@ -1212,16 +1209,16 @@ void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContex
     }
 
     auto transfer_mem =
-        system.CurrentProcess()->GetHandleTable().Get<Kernel::TransferMemory>(handle);
+        system.CurrentProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(handle);
 
-    if (transfer_mem == nullptr) {
+    if (transfer_mem.IsNull()) {
         LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle);
         IPC::ResponseBuilder rb{ctx, 2};
         rb.Push(RESULT_UNKNOWN);
         return;
     }
 
-    const u8* const mem_begin = transfer_mem->GetPointer();
+    const u8* const mem_begin = system.Memory().GetPointer(transfer_mem->GetSourceAddress());
     const u8* const mem_end = mem_begin + transfer_mem->GetSize();
     std::vector<u8> memory{mem_begin, mem_end};
 
@@ -1265,7 +1262,9 @@ void ILibraryAppletCreator::CreateHandleStorage(Kernel::HLERequestContext& ctx)
 }
 
 IApplicationFunctions::IApplicationFunctions(Core::System& system_)
-    : ServiceFramework{system_, "IApplicationFunctions"} {
+    : ServiceFramework{system_, "IApplicationFunctions"}, gpu_error_detected_event{system.Kernel()},
+      friend_invitation_storage_channel_event{system.Kernel()},
+      health_warning_disappeared_system_event{system.Kernel()} {
     // clang-format off
     static const FunctionInfo functions[] = {
         {1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"},
@@ -1334,15 +1333,11 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
     RegisterHandlers(functions);
 
     auto& kernel = system.Kernel();
-    gpu_error_detected_event =
-        Kernel::KEvent::Create(kernel, "IApplicationFunctions:GpuErrorDetectedSystemEvent");
-    gpu_error_detected_event->Initialize();
-    friend_invitation_storage_channel_event =
-        Kernel::KEvent::Create(kernel, "IApplicationFunctions:FriendInvitationStorageChannelEvent");
-    friend_invitation_storage_channel_event->Initialize();
-    health_warning_disappeared_system_event =
-        Kernel::KEvent::Create(kernel, "IApplicationFunctions:HealthWarningDisappearedSystemEvent");
-    health_warning_disappeared_system_event->Initialize();
+    gpu_error_detected_event.Initialize("IApplicationFunctions:GpuErrorDetectedSystemEvent");
+    friend_invitation_storage_channel_event.Initialize(
+        "IApplicationFunctions:FriendInvitationStorageChannelEvent");
+    health_warning_disappeared_system_event.Initialize(
+        "IApplicationFunctions:HealthWarningDisappearedSystemEvent");
 }
 
 IApplicationFunctions::~IApplicationFunctions() = default;
@@ -1739,7 +1734,7 @@ void IApplicationFunctions::GetGpuErrorDetectedSystemEvent(Kernel::HLERequestCon
 
     IPC::ResponseBuilder rb{ctx, 2, 1};
     rb.Push(RESULT_SUCCESS);
-    rb.PushCopyObjects(gpu_error_detected_event->GetReadableEvent());
+    rb.PushCopyObjects(gpu_error_detected_event.GetReadableEvent());
 }
 
 void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(Kernel::HLERequestContext& ctx) {
@@ -1747,7 +1742,7 @@ void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(Kernel::HLERe
 
     IPC::ResponseBuilder rb{ctx, 2, 1};
     rb.Push(RESULT_SUCCESS);
-    rb.PushCopyObjects(friend_invitation_storage_channel_event->GetReadableEvent());
+    rb.PushCopyObjects(friend_invitation_storage_channel_event.GetReadableEvent());
 }
 
 void IApplicationFunctions::TryPopFromFriendInvitationStorageChannel(
@@ -1763,7 +1758,7 @@ void IApplicationFunctions::GetHealthWarningDisappearedSystemEvent(Kernel::HLERe
 
     IPC::ResponseBuilder rb{ctx, 2, 1};
     rb.Push(RESULT_SUCCESS);
-    rb.PushCopyObjects(health_warning_disappeared_system_event->GetReadableEvent());
+    rb.PushCopyObjects(health_warning_disappeared_system_event.GetReadableEvent());
 }
 
 void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger,
@@ -1781,7 +1776,8 @@ void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger
 }
 
 IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_)
-    : ServiceFramework{system_, "IHomeMenuFunctions"} {
+    : ServiceFramework{system_, "IHomeMenuFunctions"}, pop_from_general_channel_event{
+                                                           system.Kernel()} {
     // clang-format off
     static const FunctionInfo functions[] = {
         {10, &IHomeMenuFunctions::RequestToGetForeground, "RequestToGetForeground"},
@@ -1802,9 +1798,7 @@ IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_)
 
     RegisterHandlers(functions);
 
-    pop_from_general_channel_event =
-        Kernel::KEvent::Create(system.Kernel(), "IHomeMenuFunctions:PopFromGeneralChannelEvent");
-    pop_from_general_channel_event->Initialize();
+    pop_from_general_channel_event.Initialize("IHomeMenuFunctions:PopFromGeneralChannelEvent");
 }
 
 IHomeMenuFunctions::~IHomeMenuFunctions() = default;
@@ -1821,7 +1815,7 @@ void IHomeMenuFunctions::GetPopFromGeneralChannelEvent(Kernel::HLERequestContext
 
     IPC::ResponseBuilder rb{ctx, 2, 1};
     rb.Push(RESULT_SUCCESS);
-    rb.PushCopyObjects(pop_from_general_channel_event->GetReadableEvent());
+    rb.PushCopyObjects(pop_from_general_channel_event.GetReadableEvent());
 }
 
 IGlobalStateController::IGlobalStateController(Core::System& system_)
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index f8daeb437b..8f6017c4e0 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -8,11 +8,11 @@
 #include <memory>
 #include <queue>
 
+#include "core/hle/kernel/k_event.h"
 #include "core/hle/service/service.h"
 
 namespace Kernel {
 class KernelCore;
-class KEvent;
 class TransferMemory;
 } // namespace Kernel
 
@@ -67,8 +67,8 @@ public:
 
 private:
     std::queue<AppletMessage> messages;
-    std::shared_ptr<Kernel::KEvent> on_new_message;
-    std::shared_ptr<Kernel::KEvent> on_operation_mode_changed;
+    Kernel::KEvent on_new_message;
+    Kernel::KEvent on_operation_mode_changed;
 };
 
 class IWindowController final : public ServiceFramework<IWindowController> {
@@ -156,8 +156,8 @@ private:
     };
 
     NVFlinger::NVFlinger& nvflinger;
-    std::shared_ptr<Kernel::KEvent> launchable_event;
-    std::shared_ptr<Kernel::KEvent> accumulated_suspended_tick_changed_event;
+    Kernel::KEvent launchable_event;
+    Kernel::KEvent accumulated_suspended_tick_changed_event;
 
     u32 idle_time_detection_extension = 0;
     u64 num_fatal_sections_entered = 0;
@@ -300,9 +300,9 @@ private:
     bool launch_popped_application_specific = false;
     bool launch_popped_account_preselect = false;
     s32 previous_program_index{-1};
-    std::shared_ptr<Kernel::KEvent> gpu_error_detected_event;
-    std::shared_ptr<Kernel::KEvent> friend_invitation_storage_channel_event;
-    std::shared_ptr<Kernel::KEvent> health_warning_disappeared_system_event;
+    Kernel::KEvent gpu_error_detected_event;
+    Kernel::KEvent friend_invitation_storage_channel_event;
+    Kernel::KEvent health_warning_disappeared_system_event;
 };
 
 class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> {
@@ -314,7 +314,7 @@ private:
     void RequestToGetForeground(Kernel::HLERequestContext& ctx);
     void GetPopFromGeneralChannelEvent(Kernel::HLERequestContext& ctx);
 
-    std::shared_ptr<Kernel::KEvent> pop_from_general_channel_event;
+    Kernel::KEvent pop_from_general_channel_event;
 };
 
 class IGlobalStateController final : public ServiceFramework<IGlobalStateController> {
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp
index c093813fe1..58bff810d5 100644
--- a/src/core/hle/service/am/applets/applets.cpp
+++ b/src/core/hle/service/am/applets/applets.cpp
@@ -12,7 +12,6 @@
 #include "core/frontend/applets/profile_select.h"
 #include "core/frontend/applets/software_keyboard.h"
 #include "core/frontend/applets/web_browser.h"
-#include "core/hle/kernel/k_event.h"
 #include "core/hle/kernel/k_readable_event.h"
 #include "core/hle/kernel/k_writable_event.h"
 #include "core/hle/kernel/server_session.h"
@@ -31,16 +30,11 @@
 namespace Service::AM::Applets {
 
 AppletDataBroker::AppletDataBroker(Core::System& system_, LibraryAppletMode applet_mode_)
-    : system{system_}, applet_mode{applet_mode_} {
-    state_changed_event =
-        Kernel::KEvent::Create(system.Kernel(), "ILibraryAppletAccessor:StateChangedEvent");
-    state_changed_event->Initialize();
-    pop_out_data_event =
-        Kernel::KEvent::Create(system.Kernel(), "ILibraryAppletAccessor:PopDataOutEvent");
-    pop_out_data_event->Initialize();
-    pop_interactive_out_data_event = Kernel::KEvent::Create(
-        system.Kernel(), "ILibraryAppletAccessor:PopInteractiveDataOutEvent");
-    pop_interactive_out_data_event->Initialize();
+    : system{system_}, applet_mode{applet_mode_}, state_changed_event{system.Kernel()},
+      pop_out_data_event{system.Kernel()}, pop_interactive_out_data_event{system.Kernel()} {
+    state_changed_event.Initialize("ILibraryAppletAccessor:StateChangedEvent");
+    pop_out_data_event.Initialize("ILibraryAppletAccessor:PopDataOutEvent");
+    pop_interactive_out_data_event.Initialize("ILibraryAppletAccessor:PopInteractiveDataOutEvent");
 }
 
 AppletDataBroker::~AppletDataBroker() = default;
@@ -67,7 +61,7 @@ std::shared_ptr<IStorage> AppletDataBroker::PopNormalDataToGame() {
 
     auto out = std::move(out_channel.front());
     out_channel.pop_front();
-    pop_out_data_event->GetWritableEvent()->Clear();
+    pop_out_data_event.GetWritableEvent()->Clear();
     return out;
 }
 
@@ -86,7 +80,7 @@ std::shared_ptr<IStorage> AppletDataBroker::PopInteractiveDataToGame() {
 
     auto out = std::move(out_interactive_channel.front());
     out_interactive_channel.pop_front();
-    pop_interactive_out_data_event->GetWritableEvent()->Clear();
+    pop_interactive_out_data_event.GetWritableEvent()->Clear();
     return out;
 }
 
@@ -105,7 +99,7 @@ void AppletDataBroker::PushNormalDataFromGame(std::shared_ptr<IStorage>&& storag
 
 void AppletDataBroker::PushNormalDataFromApplet(std::shared_ptr<IStorage>&& storage) {
     out_channel.emplace_back(std::move(storage));
-    pop_out_data_event->GetWritableEvent()->Signal();
+    pop_out_data_event.GetWritableEvent()->Signal();
 }
 
 void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& storage) {
@@ -114,11 +108,11 @@ void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& s
 
 void AppletDataBroker::PushInteractiveDataFromApplet(std::shared_ptr<IStorage>&& storage) {
     out_interactive_channel.emplace_back(std::move(storage));
-    pop_interactive_out_data_event->GetWritableEvent()->Signal();
+    pop_interactive_out_data_event.GetWritableEvent()->Signal();
 }
 
-void AppletDataBroker::SignalStateChanged() const {
-    state_changed_event->GetWritableEvent()->Signal();
+void AppletDataBroker::SignalStateChanged() {
+    state_changed_event.GetWritableEvent()->Signal();
 
     switch (applet_mode) {
     case LibraryAppletMode::AllForeground:
@@ -143,15 +137,15 @@ void AppletDataBroker::SignalStateChanged() const {
 }
 
 Kernel::KReadableEvent* AppletDataBroker::GetNormalDataEvent() const {
-    return pop_out_data_event->GetReadableEvent();
+    return pop_out_data_event.GetReadableEvent().get();
 }
 
 Kernel::KReadableEvent* AppletDataBroker::GetInteractiveDataEvent() const {
-    return pop_interactive_out_data_event->GetReadableEvent();
+    return pop_interactive_out_data_event.GetReadableEvent().get();
 }
 
 Kernel::KReadableEvent* AppletDataBroker::GetStateChangedEvent() const {
-    return state_changed_event->GetReadableEvent();
+    return state_changed_event.GetReadableEvent().get();
 }
 
 Applet::Applet(Core::System& system_, LibraryAppletMode applet_mode_)
diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h
index ffde8ced04..327843a98c 100644
--- a/src/core/hle/service/am/applets/applets.h
+++ b/src/core/hle/service/am/applets/applets.h
@@ -8,6 +8,7 @@
 #include <queue>
 
 #include "common/swap.h"
+#include "core/hle/kernel/k_event.h"
 #include "core/hle/kernel/object.h"
 
 union ResultCode;
@@ -119,13 +120,13 @@ private:
     // PopInteractiveDataToGame and PushInteractiveDataFromApplet
     std::deque<std::shared_ptr<IStorage>> out_interactive_channel;
 
-    std::shared_ptr<Kernel::KEvent> state_changed_event;
+    Kernel::KEvent state_changed_event;
 
     // Signaled on PushNormalDataFromApplet
-    std::shared_ptr<Kernel::KEvent> pop_out_data_event;
+    Kernel::KEvent pop_out_data_event;
 
     // Signaled on PushInteractiveDataFromApplet
-    std::shared_ptr<Kernel::KEvent> pop_interactive_out_data_event;
+    Kernel::KEvent pop_interactive_out_data_event;
 };
 
 class Applet {
diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp
index 75867e3492..12a025610e 100644
--- a/src/core/hle/service/aoc/aoc_u.cpp
+++ b/src/core/hle/service/aoc/aoc_u.cpp
@@ -16,7 +16,6 @@
 #include "core/file_sys/patch_manager.h"
 #include "core/file_sys/registered_cache.h"
 #include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/k_event.h"
 #include "core/hle/kernel/k_readable_event.h"
 #include "core/hle/kernel/kernel.h"
 #include "core/hle/kernel/process.h"
@@ -50,7 +49,7 @@ static std::vector<u64> AccumulateAOCTitleIDs(Core::System& system) {
 class IPurchaseEventManager final : public ServiceFramework<IPurchaseEventManager> {
 public:
     explicit IPurchaseEventManager(Core::System& system_)
-        : ServiceFramework{system_, "IPurchaseEventManager"} {
+        : ServiceFramework{system_, "IPurchaseEventManager"}, purchased_event{system.Kernel()} {
         // clang-format off
         static const FunctionInfo functions[] = {
             {0, &IPurchaseEventManager::SetDefaultDeliveryTarget, "SetDefaultDeliveryTarget"},
@@ -63,9 +62,7 @@ public:
 
         RegisterHandlers(functions);
 
-        purchased_event =
-            Kernel::KEvent::Create(system.Kernel(), "IPurchaseEventManager:PurchasedEvent");
-        purchased_event->Initialize();
+        purchased_event.Initialize("IPurchaseEventManager:PurchasedEvent");
     }
 
 private:
@@ -98,14 +95,15 @@ private:
 
         IPC::ResponseBuilder rb{ctx, 2, 1};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(purchased_event->GetReadableEvent());
+        rb.PushCopyObjects(purchased_event.GetReadableEvent());
     }
 
-    std::shared_ptr<Kernel::KEvent> purchased_event;
+    Kernel::KEvent purchased_event;
 };
 
 AOC_U::AOC_U(Core::System& system_)
-    : ServiceFramework{system_, "aoc:u"}, add_on_content{AccumulateAOCTitleIDs(system)} {
+    : ServiceFramework{system_, "aoc:u"}, add_on_content{AccumulateAOCTitleIDs(system)},
+      aoc_change_event{system.Kernel()} {
     // clang-format off
     static const FunctionInfo functions[] = {
         {0, nullptr, "CountAddOnContentByApplicationId"},
@@ -127,9 +125,7 @@ AOC_U::AOC_U(Core::System& system_)
 
     RegisterHandlers(functions);
 
-    auto& kernel = system.Kernel();
-    aoc_change_event = Kernel::KEvent::Create(kernel, "GetAddOnContentListChanged:Event");
-    aoc_change_event->Initialize();
+    aoc_change_event.Initialize("GetAddOnContentListChanged:Event");
 }
 
 AOC_U::~AOC_U() = default;
@@ -256,7 +252,7 @@ void AOC_U::GetAddOnContentListChangedEvent(Kernel::HLERequestContext& ctx) {
 
     IPC::ResponseBuilder rb{ctx, 2, 1};
     rb.Push(RESULT_SUCCESS);
-    rb.PushCopyObjects(aoc_change_event->GetReadableEvent());
+    rb.PushCopyObjects(aoc_change_event.GetReadableEvent());
 }
 
 void AOC_U::CreateEcPurchasedEventManager(Kernel::HLERequestContext& ctx) {
diff --git a/src/core/hle/service/aoc/aoc_u.h b/src/core/hle/service/aoc/aoc_u.h
index 1aa23529e5..65095baa20 100644
--- a/src/core/hle/service/aoc/aoc_u.h
+++ b/src/core/hle/service/aoc/aoc_u.h
@@ -4,6 +4,7 @@
 
 #pragma once
 
+#include "core/hle/kernel/k_event.h"
 #include "core/hle/service/service.h"
 
 namespace Core {
@@ -31,7 +32,7 @@ private:
     void CreatePermanentEcPurchasedEventManager(Kernel::HLERequestContext& ctx);
 
     std::vector<u64> add_on_content;
-    std::shared_ptr<Kernel::KEvent> aoc_change_event;
+    Kernel::KEvent aoc_change_event;
 };
 
 /// Registers all AOC services with the specified service manager.
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp
index 5f51fca9ab..4052c8e60c 100644
--- a/src/core/hle/service/audio/audout_u.cpp
+++ b/src/core/hle/service/audio/audout_u.cpp
@@ -43,9 +43,9 @@ class IAudioOut final : public ServiceFramework<IAudioOut> {
 public:
     IAudioOut(Core::System& system_, AudoutParams audio_params_, AudioCore::AudioOut& audio_core_,
               std::string&& device_name_, std::string&& unique_name)
-        : ServiceFramework{system_, "IAudioOut"}, audio_core{audio_core_},
-          device_name{std::move(device_name_)}, audio_params{audio_params_}, main_memory{
-                                                                                 system.Memory()} {
+        : ServiceFramework{system_, "IAudioOut"}, audio_core{audio_core_}, device_name{std::move(
+                                                                               device_name_)},
+          audio_params{audio_params_}, buffer_event{system.Kernel()}, main_memory{system.Memory()} {
         // clang-format off
         static const FunctionInfo functions[] = {
             {0, &IAudioOut::GetAudioOutState, "GetAudioOutState"},
@@ -67,13 +67,12 @@ public:
         RegisterHandlers(functions);
 
         // This is the event handle used to check if the audio buffer was released
-        buffer_event = Kernel::KEvent::Create(system.Kernel(), "IAudioOutBufferReleased");
-        buffer_event->Initialize();
+        buffer_event.Initialize("IAudioOutBufferReleased");
 
         stream = audio_core.OpenStream(system.CoreTiming(), audio_params.sample_rate,
                                        audio_params.channel_count, std::move(unique_name), [this] {
                                            const auto guard = LockService();
-                                           buffer_event->GetWritableEvent()->Signal();
+                                           buffer_event.GetWritableEvent()->Signal();
                                        });
     }
 
@@ -126,7 +125,7 @@ private:
 
         IPC::ResponseBuilder rb{ctx, 2, 1};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(buffer_event->GetReadableEvent());
+        rb.PushCopyObjects(buffer_event.GetReadableEvent());
     }
 
     void AppendAudioOutBufferImpl(Kernel::HLERequestContext& ctx) {
@@ -220,7 +219,7 @@ private:
     [[maybe_unused]] AudoutParams audio_params{};
 
     /// This is the event handle used to check if the audio buffer was released
-    std::shared_ptr<Kernel::KEvent> buffer_event;
+    Kernel::KEvent buffer_event;
     Core::Memory::Memory& main_memory;
 };
 
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index 3a48342fd9..d573530df3 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -30,7 +30,7 @@ public:
     explicit IAudioRenderer(Core::System& system_,
                             const AudioCommon::AudioRendererParameter& audren_params,
                             const std::size_t instance_number)
-        : ServiceFramework{system_, "IAudioRenderer"} {
+        : ServiceFramework{system_, "IAudioRenderer"}, system_event{system.Kernel()} {
         // clang-format off
         static const FunctionInfo functions[] = {
             {0, &IAudioRenderer::GetSampleRate, "GetSampleRate"},
@@ -49,13 +49,12 @@ public:
         // clang-format on
         RegisterHandlers(functions);
 
-        system_event = Kernel::KEvent::Create(system.Kernel(), "IAudioRenderer:SystemEvent");
-        system_event->Initialize();
+        system_event.Initialize("IAudioRenderer:SystemEvent");
         renderer = std::make_unique<AudioCore::AudioRenderer>(
             system.CoreTiming(), system.Memory(), audren_params,
             [this]() {
                 const auto guard = LockService();
-                system_event->GetWritableEvent()->Signal();
+                system_event.GetWritableEvent()->Signal();
             },
             instance_number);
     }
@@ -128,7 +127,7 @@ private:
 
         IPC::ResponseBuilder rb{ctx, 2, 1};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(system_event->GetReadableEvent());
+        rb.PushCopyObjects(system_event.GetReadableEvent());
     }
 
     void SetRenderingTimeLimit(Kernel::HLERequestContext& ctx) {
@@ -162,7 +161,7 @@ private:
         rb.Push(ERR_NOT_SUPPORTED);
     }
 
-    std::shared_ptr<Kernel::KEvent> system_event;
+    Kernel::KEvent system_event;
     std::unique_ptr<AudioCore::AudioRenderer> renderer;
     u32 rendering_time_limit_percent = 100;
 };
@@ -170,7 +169,9 @@ private:
 class IAudioDevice final : public ServiceFramework<IAudioDevice> {
 public:
     explicit IAudioDevice(Core::System& system_, u32_le revision_num)
-        : ServiceFramework{system_, "IAudioDevice"}, revision{revision_num} {
+        : ServiceFramework{system_, "IAudioDevice"}, revision{revision_num},
+          buffer_event{system.Kernel()}, audio_input_device_switch_event{system.Kernel()},
+          audio_output_device_switch_event{system.Kernel()} {
         static const FunctionInfo functions[] = {
             {0, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceName"},
             {1, &IAudioDevice::SetAudioDeviceOutputVolume, "SetAudioDeviceOutputVolume"},
@@ -188,20 +189,14 @@ public:
         };
         RegisterHandlers(functions);
 
-        auto& kernel = system.Kernel();
-        buffer_event = Kernel::KEvent::Create(kernel, "IAudioOutBufferReleasedEvent");
-        buffer_event->Initialize();
+        buffer_event.Initialize("IAudioOutBufferReleasedEvent");
 
         // Should be similar to audio_output_device_switch_event
-        audio_input_device_switch_event =
-            Kernel::KEvent::Create(kernel, "IAudioDevice:AudioInputDeviceSwitchedEvent");
-        audio_input_device_switch_event->Initialize();
+        audio_input_device_switch_event.Initialize("IAudioDevice:AudioInputDeviceSwitchedEvent");
 
         // Should only be signalled when an audio output device has been changed, example: speaker
         // to headset
-        audio_output_device_switch_event =
-            Kernel::KEvent::Create(kernel, "IAudioDevice:AudioOutputDeviceSwitchedEvent");
-        audio_output_device_switch_event->Initialize();
+        audio_output_device_switch_event.Initialize("IAudioDevice:AudioOutputDeviceSwitchedEvent");
     }
 
 private:
@@ -290,11 +285,11 @@ private:
     void QueryAudioDeviceSystemEvent(Kernel::HLERequestContext& ctx) {
         LOG_WARNING(Service_Audio, "(STUBBED) called");
 
-        buffer_event->GetWritableEvent()->Signal();
+        buffer_event.GetWritableEvent()->Signal();
 
         IPC::ResponseBuilder rb{ctx, 2, 1};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(buffer_event->GetReadableEvent());
+        rb.PushCopyObjects(buffer_event.GetReadableEvent());
     }
 
     void GetActiveChannelCount(Kernel::HLERequestContext& ctx) {
@@ -311,7 +306,7 @@ private:
 
         IPC::ResponseBuilder rb{ctx, 2, 1};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(audio_input_device_switch_event->GetReadableEvent());
+        rb.PushCopyObjects(audio_input_device_switch_event.GetReadableEvent());
     }
 
     void QueryAudioDeviceOutputEvent(Kernel::HLERequestContext& ctx) {
@@ -319,13 +314,13 @@ private:
 
         IPC::ResponseBuilder rb{ctx, 2, 1};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(audio_output_device_switch_event->GetReadableEvent());
+        rb.PushCopyObjects(audio_output_device_switch_event.GetReadableEvent());
     }
 
     u32_le revision = 0;
-    std::shared_ptr<Kernel::KEvent> buffer_event;
-    std::shared_ptr<Kernel::KEvent> audio_input_device_switch_event;
-    std::shared_ptr<Kernel::KEvent> audio_output_device_switch_event;
+    Kernel::KEvent buffer_event;
+    Kernel::KEvent audio_input_device_switch_event;
+    Kernel::KEvent audio_output_device_switch_event;
 
 }; // namespace Audio
 
diff --git a/src/core/hle/service/bcat/backend/backend.cpp b/src/core/hle/service/bcat/backend/backend.cpp
index 7f301fdeb0..932e70bfd3 100644
--- a/src/core/hle/service/bcat/backend/backend.cpp
+++ b/src/core/hle/service/bcat/backend/backend.cpp
@@ -5,7 +5,6 @@
 #include "common/hex_util.h"
 #include "common/logging/log.h"
 #include "core/core.h"
-#include "core/hle/kernel/k_event.h"
 #include "core/hle/kernel/k_readable_event.h"
 #include "core/hle/kernel/k_writable_event.h"
 #include "core/hle/lock.h"
@@ -14,14 +13,13 @@
 namespace Service::BCAT {
 
 ProgressServiceBackend::ProgressServiceBackend(Kernel::KernelCore& kernel,
-                                               std::string_view event_name) {
-    event = Kernel::KEvent::Create(kernel,
-                                   "ProgressServiceBackend:UpdateEvent:" + std::string(event_name));
-    event->Initialize();
+                                               std::string_view event_name)
+    : update_event{kernel} {
+    update_event.Initialize("ProgressServiceBackend:UpdateEvent:" + std::string(event_name));
 }
 
 std::shared_ptr<Kernel::KReadableEvent> ProgressServiceBackend::GetEvent() const {
-    return SharedFrom(event->GetReadableEvent());
+    return update_event.GetReadableEvent();
 }
 
 DeliveryCacheProgressImpl& ProgressServiceBackend::GetImpl() {
@@ -89,9 +87,9 @@ void ProgressServiceBackend::FinishDownload(ResultCode result) {
 void ProgressServiceBackend::SignalUpdate() const {
     if (need_hle_lock) {
         std::lock_guard lock(HLE::g_hle_lock);
-        event->GetWritableEvent()->Signal();
+        update_event.GetWritableEvent()->Signal();
     } else {
-        event->GetWritableEvent()->Signal();
+        update_event.GetWritableEvent()->Signal();
     }
 }
 
diff --git a/src/core/hle/service/bcat/backend/backend.h b/src/core/hle/service/bcat/backend/backend.h
index db585b0690..baa4d576a7 100644
--- a/src/core/hle/service/bcat/backend/backend.h
+++ b/src/core/hle/service/bcat/backend/backend.h
@@ -11,6 +11,7 @@
 
 #include "common/common_types.h"
 #include "core/file_sys/vfs_types.h"
+#include "core/hle/kernel/k_event.h"
 #include "core/hle/result.h"
 
 namespace Core {
@@ -104,7 +105,7 @@ private:
     void SignalUpdate() const;
 
     DeliveryCacheProgressImpl impl{};
-    std::shared_ptr<Kernel::KEvent> event;
+    Kernel::KEvent update_event;
     bool need_hle_lock = false;
 };
 
diff --git a/src/core/hle/service/btdrv/btdrv.cpp b/src/core/hle/service/btdrv/btdrv.cpp
index af3a5842df..dde276ff48 100644
--- a/src/core/hle/service/btdrv/btdrv.cpp
+++ b/src/core/hle/service/btdrv/btdrv.cpp
@@ -17,7 +17,8 @@ namespace Service::BtDrv {
 
 class Bt final : public ServiceFramework<Bt> {
 public:
-    explicit Bt(Core::System& system_) : ServiceFramework{system_, "bt"} {
+    explicit Bt(Core::System& system_)
+        : ServiceFramework{system_, "bt"}, register_event{system.Kernel()} {
         // clang-format off
         static const FunctionInfo functions[] = {
             {0, nullptr, "LeClientReadCharacteristic"},
@@ -34,9 +35,7 @@ public:
         // clang-format on
         RegisterHandlers(functions);
 
-        auto& kernel = system.Kernel();
-        register_event = Kernel::KEvent::Create(kernel, "BT:RegisterEvent");
-        register_event->Initialize();
+        register_event.Initialize("BT:RegisterEvent");
     }
 
 private:
@@ -45,10 +44,10 @@ private:
 
         IPC::ResponseBuilder rb{ctx, 2, 1};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(register_event->GetReadableEvent());
+        rb.PushCopyObjects(register_event.GetReadableEvent());
     }
 
-    std::shared_ptr<Kernel::KEvent> register_event;
+    Kernel::KEvent register_event;
 };
 
 class BtDrv final : public ServiceFramework<BtDrv> {
diff --git a/src/core/hle/service/btm/btm.cpp b/src/core/hle/service/btm/btm.cpp
index d1ebc23881..403296650a 100644
--- a/src/core/hle/service/btm/btm.cpp
+++ b/src/core/hle/service/btm/btm.cpp
@@ -18,7 +18,10 @@ namespace Service::BTM {
 
 class IBtmUserCore final : public ServiceFramework<IBtmUserCore> {
 public:
-    explicit IBtmUserCore(Core::System& system_) : ServiceFramework{system_, "IBtmUserCore"} {
+    explicit IBtmUserCore(Core::System& system_)
+        : ServiceFramework{system_, "IBtmUserCore"}, scan_event{system.Kernel()},
+          connection_event{system.Kernel()}, service_discovery{system.Kernel()},
+          config_event{system.Kernel()} {
         // clang-format off
         static const FunctionInfo functions[] = {
             {0, &IBtmUserCore::AcquireBleScanEvent, "AcquireBleScanEvent"},
@@ -57,15 +60,10 @@ public:
         // clang-format on
         RegisterHandlers(functions);
 
-        auto& kernel = system.Kernel();
-        scan_event = Kernel::KEvent::Create(kernel, "IBtmUserCore:ScanEvent");
-        scan_event->Initialize();
-        connection_event = Kernel::KEvent::Create(kernel, "IBtmUserCore:ConnectionEvent");
-        connection_event->Initialize();
-        service_discovery = Kernel::KEvent::Create(kernel, "IBtmUserCore:Discovery");
-        service_discovery->Initialize();
-        config_event = Kernel::KEvent::Create(kernel, "IBtmUserCore:ConfigEvent");
-        config_event->Initialize();
+        scan_event.Initialize("IBtmUserCore:ScanEvent");
+        connection_event.Initialize("IBtmUserCore:ConnectionEvent");
+        service_discovery.Initialize("IBtmUserCore:Discovery");
+        config_event.Initialize("IBtmUserCore:ConfigEvent");
     }
 
 private:
@@ -74,7 +72,7 @@ private:
 
         IPC::ResponseBuilder rb{ctx, 2, 1};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(scan_event->GetReadableEvent());
+        rb.PushCopyObjects(scan_event.GetReadableEvent());
     }
 
     void AcquireBleConnectionEvent(Kernel::HLERequestContext& ctx) {
@@ -82,7 +80,7 @@ private:
 
         IPC::ResponseBuilder rb{ctx, 2, 1};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(connection_event->GetReadableEvent());
+        rb.PushCopyObjects(connection_event.GetReadableEvent());
     }
 
     void AcquireBleServiceDiscoveryEvent(Kernel::HLERequestContext& ctx) {
@@ -90,7 +88,7 @@ private:
 
         IPC::ResponseBuilder rb{ctx, 2, 1};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(service_discovery->GetReadableEvent());
+        rb.PushCopyObjects(service_discovery.GetReadableEvent());
     }
 
     void AcquireBleMtuConfigEvent(Kernel::HLERequestContext& ctx) {
@@ -98,13 +96,13 @@ private:
 
         IPC::ResponseBuilder rb{ctx, 2, 1};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(config_event->GetReadableEvent());
+        rb.PushCopyObjects(config_event.GetReadableEvent());
     }
 
-    std::shared_ptr<Kernel::KEvent> scan_event;
-    std::shared_ptr<Kernel::KEvent> connection_event;
-    std::shared_ptr<Kernel::KEvent> service_discovery;
-    std::shared_ptr<Kernel::KEvent> config_event;
+    Kernel::KEvent scan_event;
+    Kernel::KEvent connection_event;
+    Kernel::KEvent service_discovery;
+    Kernel::KEvent config_event;
 };
 
 class BTM_USR final : public ServiceFramework<BTM_USR> {
diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp
index a359790532..526b0f8963 100644
--- a/src/core/hle/service/friend/friend.cpp
+++ b/src/core/hle/service/friend/friend.cpp
@@ -185,7 +185,8 @@ private:
 class INotificationService final : public ServiceFramework<INotificationService> {
 public:
     explicit INotificationService(Common::UUID uuid_, Core::System& system_)
-        : ServiceFramework{system_, "INotificationService"}, uuid{uuid_} {
+        : ServiceFramework{system_, "INotificationService"}, uuid{uuid_}, notification_event{
+                                                                              system.Kernel()} {
         // clang-format off
         static const FunctionInfo functions[] = {
             {0, &INotificationService::GetEvent, "GetEvent"},
@@ -196,9 +197,7 @@ public:
 
         RegisterHandlers(functions);
 
-        notification_event =
-            Kernel::KEvent::Create(system.Kernel(), "INotificationService:NotifyEvent");
-        notification_event->Initialize();
+        notification_event.Initialize("INotificationService:NotifyEvent");
     }
 
 private:
@@ -207,7 +206,7 @@ private:
 
         IPC::ResponseBuilder rb{ctx, 2, 1};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(notification_event->GetReadableEvent());
+        rb.PushCopyObjects(notification_event.GetReadableEvent());
     }
 
     void Clear(Kernel::HLERequestContext& ctx) {
@@ -273,7 +272,7 @@ private:
     };
 
     Common::UUID uuid{Common::INVALID_UUID};
-    std::shared_ptr<Kernel::KEvent> notification_event;
+    Kernel::KEvent notification_event;
     std::queue<SizedNotificationInfo> notifications;
     States states{};
 };
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 9d07ca09ca..7d9debc092 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -253,9 +253,8 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) {
 void Controller_NPad::OnInit() {
     auto& kernel = system.Kernel();
     for (std::size_t i = 0; i < styleset_changed_events.size(); ++i) {
-        styleset_changed_events[i] =
-            Kernel::KEvent::Create(kernel, fmt::format("npad:NpadStyleSetChanged_{}", i));
-        styleset_changed_events[i]->Initialize();
+        styleset_changed_events[i] = std::make_unique<Kernel::KEvent>(kernel);
+        styleset_changed_events[i]->Initialize(fmt::format("npad:NpadStyleSetChanged_{}", i));
     }
 
     if (!IsControllerActivated()) {
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index 8c24728b1f..515cf7c371 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -573,7 +573,7 @@ private:
     NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual};
     NpadCommunicationMode communication_mode{NpadCommunicationMode::Default};
     // Each controller should have their own styleset changed event
-    std::array<std::shared_ptr<Kernel::KEvent>, 10> styleset_changed_events;
+    std::array<std::unique_ptr<Kernel::KEvent>, 10> styleset_changed_events;
     std::array<std::array<std::chrono::steady_clock::time_point, 2>, 10> last_vibration_timepoints;
     std::array<std::array<VibrationValue, 2>, 10> latest_vibration_values{};
     bool permit_vibration_session_enabled{false};
diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp
index 1446c0bcff..164b8b9cd6 100644
--- a/src/core/hle/service/nfp/nfp.cpp
+++ b/src/core/hle/service/nfp/nfp.cpp
@@ -8,7 +8,6 @@
 #include "common/logging/log.h"
 #include "core/core.h"
 #include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/k_event.h"
 #include "core/hle/kernel/k_readable_event.h"
 #include "core/hle/kernel/k_thread.h"
 #include "core/hle/kernel/k_writable_event.h"
@@ -24,10 +23,8 @@ constexpr ResultCode ERR_NO_APPLICATION_AREA(ErrorModule::NFP, 152);
 
 Module::Interface::Interface(std::shared_ptr<Module> module_, Core::System& system_,
                              const char* name)
-    : ServiceFramework{system_, name}, module{std::move(module_)} {
-    auto& kernel = system.Kernel();
-    nfc_tag_load = Kernel::KEvent::Create(kernel, "IUser:NFCTagDetected");
-    nfc_tag_load->Initialize();
+    : ServiceFramework{system_, name}, nfc_tag_load{system.Kernel()}, module{std::move(module_)} {
+    nfc_tag_load.Initialize("IUser:NFCTagDetected");
 }
 
 Module::Interface::~Interface() = default;
@@ -35,7 +32,8 @@ Module::Interface::~Interface() = default;
 class IUser final : public ServiceFramework<IUser> {
 public:
     explicit IUser(Module::Interface& nfp_interface_, Core::System& system_)
-        : ServiceFramework{system_, "NFP::IUser"}, nfp_interface{nfp_interface_} {
+        : ServiceFramework{system_, "NFP::IUser"}, nfp_interface{nfp_interface_},
+          deactivate_event{system.Kernel()}, availability_change_event{system.Kernel()} {
         static const FunctionInfo functions[] = {
             {0, &IUser::Initialize, "Initialize"},
             {1, &IUser::Finalize, "Finalize"},
@@ -65,11 +63,8 @@ public:
         };
         RegisterHandlers(functions);
 
-        auto& kernel = system.Kernel();
-        deactivate_event = Kernel::KEvent::Create(kernel, "IUser:DeactivateEvent");
-        deactivate_event->Initialize();
-        availability_change_event = Kernel::KEvent::Create(kernel, "IUser:AvailabilityChangeEvent");
-        availability_change_event->Initialize();
+        deactivate_event.Initialize("IUser:DeactivateEvent");
+        availability_change_event.Initialize("IUser:AvailabilityChangeEvent");
     }
 
 private:
@@ -167,7 +162,7 @@ private:
 
         IPC::ResponseBuilder rb{ctx, 2, 1};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(deactivate_event->GetReadableEvent());
+        rb.PushCopyObjects(deactivate_event.GetReadableEvent());
     }
 
     void StopDetection(Kernel::HLERequestContext& ctx) {
@@ -176,7 +171,7 @@ private:
         switch (device_state) {
         case DeviceState::TagFound:
         case DeviceState::TagNearby:
-            deactivate_event->GetWritableEvent()->Signal();
+            deactivate_event.GetWritableEvent()->Signal();
             device_state = DeviceState::Initialized;
             break;
         case DeviceState::SearchingForTag:
@@ -265,7 +260,7 @@ private:
 
         IPC::ResponseBuilder rb{ctx, 2, 1};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(availability_change_event->GetReadableEvent());
+        rb.PushCopyObjects(availability_change_event.GetReadableEvent());
     }
 
     void GetRegisterInfo(Kernel::HLERequestContext& ctx) {
@@ -319,9 +314,9 @@ private:
     const u32 npad_id{0};       // Player 1 controller
     State state{State::NonInitialized};
     DeviceState device_state{DeviceState::Initialized};
-    std::shared_ptr<Kernel::KEvent> deactivate_event;
-    std::shared_ptr<Kernel::KEvent> availability_change_event;
     const Module::Interface& nfp_interface;
+    Kernel::KEvent deactivate_event;
+    Kernel::KEvent availability_change_event;
 };
 
 void Module::Interface::CreateUserInterface(Kernel::HLERequestContext& ctx) {
@@ -339,12 +334,12 @@ bool Module::Interface::LoadAmiibo(const std::vector<u8>& buffer) {
     }
 
     std::memcpy(&amiibo, buffer.data(), sizeof(amiibo));
-    nfc_tag_load->GetWritableEvent()->Signal();
+    nfc_tag_load.GetWritableEvent()->Signal();
     return true;
 }
 
 Kernel::KReadableEvent* Module::Interface::GetNFCEvent() const {
-    return nfc_tag_load->GetReadableEvent();
+    return nfc_tag_load.GetReadableEvent().get();
 }
 
 const Module::Interface::AmiiboFile& Module::Interface::GetAmiiboBuffer() const {
diff --git a/src/core/hle/service/nfp/nfp.h b/src/core/hle/service/nfp/nfp.h
index 7a97caffb1..4bca2192c1 100644
--- a/src/core/hle/service/nfp/nfp.h
+++ b/src/core/hle/service/nfp/nfp.h
@@ -7,6 +7,7 @@
 #include <array>
 #include <vector>
 
+#include "core/hle/kernel/k_event.h"
 #include "core/hle/service/service.h"
 
 namespace Kernel {
@@ -42,7 +43,7 @@ public:
         const AmiiboFile& GetAmiiboBuffer() const;
 
     private:
-        std::shared_ptr<Kernel::KEvent> nfc_tag_load;
+        Kernel::KEvent nfc_tag_load;
         AmiiboFile amiibo{};
 
     protected:
diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp
index 9f110df8e8..fe1c257575 100644
--- a/src/core/hle/service/nifm/nifm.cpp
+++ b/src/core/hle/service/nifm/nifm.cpp
@@ -127,7 +127,8 @@ public:
 
 class IRequest final : public ServiceFramework<IRequest> {
 public:
-    explicit IRequest(Core::System& system_) : ServiceFramework{system_, "IRequest"} {
+    explicit IRequest(Core::System& system_)
+        : ServiceFramework{system_, "IRequest"}, event1{system.Kernel()}, event2{system.Kernel()} {
         static const FunctionInfo functions[] = {
             {0, &IRequest::GetRequestState, "GetRequestState"},
             {1, &IRequest::GetResult, "GetResult"},
@@ -159,10 +160,8 @@ public:
 
         auto& kernel = system.Kernel();
 
-        event1 = Kernel::KEvent::Create(kernel, "IRequest:Event1");
-        event1->Initialize();
-        event2 = Kernel::KEvent::Create(kernel, "IRequest:Event2");
-        event2->Initialize();
+        event1.Initialize("IRequest:Event1");
+        event2.Initialize("IRequest:Event2");
     }
 
 private:
@@ -198,7 +197,7 @@ private:
 
         IPC::ResponseBuilder rb{ctx, 2, 2};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(event1->GetReadableEvent(), event2->GetReadableEvent());
+        rb.PushCopyObjects(event1.GetReadableEvent(), event2.GetReadableEvent());
     }
 
     void Cancel(Kernel::HLERequestContext& ctx) {
@@ -229,7 +228,7 @@ private:
         rb.Push<u32>(0);
     }
 
-    std::shared_ptr<Kernel::KEvent> event1, event2;
+    Kernel::KEvent event1, event2;
 };
 
 class INetworkProfile final : public ServiceFramework<INetworkProfile> {
diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp
index fee360ab9c..6d66ad90b2 100644
--- a/src/core/hle/service/nim/nim.cpp
+++ b/src/core/hle/service/nim/nim.cpp
@@ -300,7 +300,8 @@ class IEnsureNetworkClockAvailabilityService final
     : public ServiceFramework<IEnsureNetworkClockAvailabilityService> {
 public:
     explicit IEnsureNetworkClockAvailabilityService(Core::System& system_)
-        : ServiceFramework{system_, "IEnsureNetworkClockAvailabilityService"} {
+        : ServiceFramework{system_, "IEnsureNetworkClockAvailabilityService"},
+          finished_event{system.Kernel()} {
         static const FunctionInfo functions[] = {
             {0, &IEnsureNetworkClockAvailabilityService::StartTask, "StartTask"},
             {1, &IEnsureNetworkClockAvailabilityService::GetFinishNotificationEvent,
@@ -312,19 +313,16 @@ public:
         };
         RegisterHandlers(functions);
 
-        auto& kernel = system.Kernel();
-        finished_event =
-            Kernel::KEvent::Create(kernel, "IEnsureNetworkClockAvailabilityService:FinishEvent");
-        finished_event->Initialize();
+        finished_event.Initialize("IEnsureNetworkClockAvailabilityService:FinishEvent");
     }
 
 private:
-    std::shared_ptr<Kernel::KEvent> finished_event;
+    Kernel::KEvent finished_event;
 
     void StartTask(Kernel::HLERequestContext& ctx) {
         // No need to connect to the internet, just finish the task straight away.
         LOG_DEBUG(Service_NIM, "called");
-        finished_event->GetWritableEvent()->Signal();
+        finished_event.GetWritableEvent()->Signal();
         IPC::ResponseBuilder rb{ctx, 2};
         rb.Push(RESULT_SUCCESS);
     }
@@ -334,7 +332,7 @@ private:
 
         IPC::ResponseBuilder rb{ctx, 2, 1};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(finished_event->GetReadableEvent());
+        rb.PushCopyObjects(finished_event.GetReadableEvent());
     }
 
     void GetResult(Kernel::HLERequestContext& ctx) {
@@ -346,7 +344,7 @@ private:
 
     void Cancel(Kernel::HLERequestContext& ctx) {
         LOG_DEBUG(Service_NIM, "called");
-        finished_event->GetWritableEvent()->Clear();
+        finished_event.GetWritableEvent()->Clear();
         IPC::ResponseBuilder rb{ctx, 2};
         rb.Push(RESULT_SUCCESS);
     }
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
index 6f40072948..e99da24ab6 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
@@ -102,7 +102,7 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
         return NvResult::Success;
     }
 
-    auto event = events_interface.events[event_id];
+    auto& event = events_interface.events[event_id];
     auto& gpu = system.GPU();
 
     // This is mostly to take into account unimplemented features. As synced
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp
index 6bba9c0b3e..74399bcdbb 100644
--- a/src/core/hle/service/nvdrv/nvdrv.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv.cpp
@@ -42,9 +42,8 @@ void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger
 Module::Module(Core::System& system) : syncpoint_manager{system.GPU()} {
     auto& kernel = system.Kernel();
     for (u32 i = 0; i < MaxNvEvents; i++) {
-        std::string event_label = fmt::format("NVDRV::NvEvent_{}", i);
-        events_interface.events[i] = {Kernel::KEvent::Create(kernel, std::move(event_label))};
-        events_interface.events[i].event->Initialize();
+        events_interface.events[i].event = std::make_unique<Kernel::KEvent>(kernel);
+        events_interface.events[i].event->Initialize(fmt::format("NVDRV::NvEvent_{}", i));
         events_interface.status[i] = EventState::Free;
         events_interface.registered[i] = false;
     }
@@ -64,7 +63,12 @@ Module::Module(Core::System& system) : syncpoint_manager{system.GPU()} {
         std::make_shared<Devices::nvhost_vic>(system, nvmap_dev, syncpoint_manager);
 }
 
-Module::~Module() = default;
+Module::~Module() {
+    for (u32 i = 0; i < MaxNvEvents; i++) {
+        events_interface.events[i].event->Close();
+        events_interface.events[i].event = nullptr;
+    }
+}
 
 NvResult Module::VerifyFD(DeviceFD fd) const {
     if (fd < 0) {
diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h
index 53719aadda..76f77cbb19 100644
--- a/src/core/hle/service/nvdrv/nvdrv.h
+++ b/src/core/hle/service/nvdrv/nvdrv.h
@@ -35,7 +35,7 @@ class nvdevice;
 
 /// Represents an Nvidia event
 struct NvEvent {
-    std::shared_ptr<Kernel::KEvent> event;
+    std::unique_ptr<Kernel::KEvent> event;
     Fence fence{};
 };
 
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp
index f783ae54fd..8ddb1f9083 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.cpp
+++ b/src/core/hle/service/nvflinger/buffer_queue.cpp
@@ -7,7 +7,6 @@
 #include "common/assert.h"
 #include "common/logging/log.h"
 #include "core/core.h"
-#include "core/hle/kernel/k_event.h"
 #include "core/hle/kernel/k_writable_event.h"
 #include "core/hle/kernel/kernel.h"
 #include "core/hle/service/nvflinger/buffer_queue.h"
@@ -15,9 +14,8 @@
 namespace Service::NVFlinger {
 
 BufferQueue::BufferQueue(Kernel::KernelCore& kernel, u32 id, u64 layer_id)
-    : id(id), layer_id(layer_id) {
-    buffer_wait_event = Kernel::KEvent::Create(kernel, "BufferQueue:WaitEvent");
-    buffer_wait_event->Initialize();
+    : id(id), layer_id(layer_id), buffer_wait_event{kernel} {
+    buffer_wait_event.Initialize("BufferQueue:WaitEvent");
 }
 
 BufferQueue::~BufferQueue() = default;
@@ -42,7 +40,7 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer)
         .multi_fence = {},
     };
 
-    buffer_wait_event->GetWritableEvent()->Signal();
+    buffer_wait_event.GetWritableEvent()->Signal();
 }
 
 std::optional<std::pair<u32, Service::Nvidia::MultiFence*>> BufferQueue::DequeueBuffer(u32 width,
@@ -120,7 +118,7 @@ void BufferQueue::CancelBuffer(u32 slot, const Service::Nvidia::MultiFence& mult
     }
     free_buffers_condition.notify_one();
 
-    buffer_wait_event->GetWritableEvent()->Signal();
+    buffer_wait_event.GetWritableEvent()->Signal();
 }
 
 std::optional<std::reference_wrapper<const BufferQueue::Buffer>> BufferQueue::AcquireBuffer() {
@@ -155,7 +153,7 @@ void BufferQueue::ReleaseBuffer(u32 slot) {
     }
     free_buffers_condition.notify_one();
 
-    buffer_wait_event->GetWritableEvent()->Signal();
+    buffer_wait_event.GetWritableEvent()->Signal();
 }
 
 void BufferQueue::Connect() {
@@ -170,7 +168,7 @@ void BufferQueue::Disconnect() {
         std::unique_lock lock{queue_sequence_mutex};
         queue_sequence.clear();
     }
-    buffer_wait_event->GetWritableEvent()->Signal();
+    buffer_wait_event.GetWritableEvent()->Signal();
     is_connect = false;
     free_buffers_condition.notify_one();
 }
@@ -190,11 +188,11 @@ u32 BufferQueue::Query(QueryType type) {
 }
 
 std::shared_ptr<Kernel::KWritableEvent> BufferQueue::GetWritableBufferWaitEvent() const {
-    return buffer_wait_event->GetWritableEvent();
+    return buffer_wait_event.GetWritableEvent();
 }
 
 std::shared_ptr<Kernel::KReadableEvent> BufferQueue::GetBufferWaitEvent() const {
-    return SharedFrom(buffer_wait_event->GetReadableEvent());
+    return buffer_wait_event.GetReadableEvent();
 }
 
 } // namespace Service::NVFlinger
diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h
index 9a21c74261..0d2010ad51 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.h
+++ b/src/core/hle/service/nvflinger/buffer_queue.h
@@ -13,6 +13,7 @@
 #include "common/common_funcs.h"
 #include "common/math_util.h"
 #include "common/swap.h"
+#include "core/hle/kernel/k_event.h"
 #include "core/hle/kernel/k_readable_event.h"
 #include "core/hle/kernel/object.h"
 #include "core/hle/service/nvdrv/nvdata.h"
@@ -130,7 +131,7 @@ private:
     std::list<u32> free_buffers;
     std::array<Buffer, buffer_slots> buffers;
     std::list<u32> queue_sequence;
-    std::shared_ptr<Kernel::KEvent> buffer_wait_event;
+    Kernel::KEvent buffer_wait_event;
 
     std::mutex free_buffers_mutex;
     std::condition_variable free_buffers_condition;
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index c43593e7fe..c90e4d0835 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -165,8 +165,8 @@ std::optional<u32> NVFlinger::FindBufferQueueId(u64 display_id, u64 layer_id) co
     return layer->GetBufferQueue().GetId();
 }
 
-std::shared_ptr<Kernel::KReadableEvent> NVFlinger::FindVsyncEvent(u64 display_id) const {
-    const auto lock_guard = Lock();
+std::shared_ptr<Kernel::KReadableEvent> NVFlinger::FindVsyncEvent(u64 display_id) {
+        const auto lock_guard = Lock();
     auto* const display = FindDisplay(display_id);
 
     if (display == nullptr) {
diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h
index 6fe2c7f2a9..d51b905c1c 100644
--- a/src/core/hle/service/nvflinger/nvflinger.h
+++ b/src/core/hle/service/nvflinger/nvflinger.h
@@ -5,6 +5,7 @@
 #pragma once
 
 #include <atomic>
+#include <list>
 #include <memory>
 #include <mutex>
 #include <optional>
@@ -72,7 +73,7 @@ public:
     /// Gets the vsync event for the specified display.
     ///
     /// If an invalid display ID is provided, then nullptr is returned.
-    [[nodiscard]] std::shared_ptr<Kernel::KReadableEvent> FindVsyncEvent(u64 display_id) const;
+    [[nodiscard]] std::shared_ptr<Kernel::KReadableEvent> FindVsyncEvent(u64 display_id);
 
     /// Obtains a buffer queue identified by the ID.
     [[nodiscard]] BufferQueue* FindBufferQueue(u32 id);
@@ -106,7 +107,7 @@ private:
 
     std::shared_ptr<Nvidia::Module> nvdrv;
 
-    std::vector<VI::Display> displays;
+    std::list<VI::Display> displays;
     std::vector<std::unique_ptr<BufferQueue>> buffer_queues;
 
     /// Id to use for the next layer that is created, this counter is shared among all displays.
diff --git a/src/core/hle/service/ptm/psm.cpp b/src/core/hle/service/ptm/psm.cpp
index 26ed52273d..22e5d9749f 100644
--- a/src/core/hle/service/ptm/psm.cpp
+++ b/src/core/hle/service/ptm/psm.cpp
@@ -19,7 +19,8 @@ namespace Service::PSM {
 
 class IPsmSession final : public ServiceFramework<IPsmSession> {
 public:
-    explicit IPsmSession(Core::System& system_) : ServiceFramework{system_, "IPsmSession"} {
+    explicit IPsmSession(Core::System& system_)
+        : ServiceFramework{system_, "IPsmSession"}, state_change_event{system.Kernel()} {
         // clang-format off
         static const FunctionInfo functions[] = {
             {0, &IPsmSession::BindStateChangeEvent, "BindStateChangeEvent"},
@@ -32,28 +33,26 @@ public:
 
         RegisterHandlers(functions);
 
-        state_change_event =
-            Kernel::KEvent::Create(system_.Kernel(), "IPsmSession::state_change_event");
-        state_change_event->Initialize();
+        state_change_event.Initialize("IPsmSession::state_change_event");
     }
 
     ~IPsmSession() override = default;
 
     void SignalChargerTypeChanged() {
         if (should_signal && should_signal_charger_type) {
-            state_change_event->GetWritableEvent()->Signal();
+            state_change_event.GetWritableEvent()->Signal();
         }
     }
 
     void SignalPowerSupplyChanged() {
         if (should_signal && should_signal_power_supply) {
-            state_change_event->GetWritableEvent()->Signal();
+            state_change_event.GetWritableEvent()->Signal();
         }
     }
 
     void SignalBatteryVoltageStateChanged() {
         if (should_signal && should_signal_battery_voltage) {
-            state_change_event->GetWritableEvent()->Signal();
+            state_change_event.GetWritableEvent()->Signal();
         }
     }
 
@@ -65,7 +64,7 @@ private:
 
         IPC::ResponseBuilder rb{ctx, 2, 1};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(state_change_event->GetReadableEvent());
+        rb.PushCopyObjects(state_change_event.GetReadableEvent());
     }
 
     void UnbindStateChangeEvent(Kernel::HLERequestContext& ctx) {
@@ -114,7 +113,7 @@ private:
     bool should_signal_power_supply{};
     bool should_signal_battery_voltage{};
     bool should_signal{};
-    std::shared_ptr<Kernel::KEvent> state_change_event;
+    Kernel::KEvent state_change_event;
 };
 
 class PSM final : public ServiceFramework<PSM> {
diff --git a/src/core/hle/service/time/standard_user_system_clock_core.cpp b/src/core/hle/service/time/standard_user_system_clock_core.cpp
index 3172acc5a8..c41bdd48b9 100644
--- a/src/core/hle/service/time/standard_user_system_clock_core.cpp
+++ b/src/core/hle/service/time/standard_user_system_clock_core.cpp
@@ -4,7 +4,6 @@
 
 #include "common/assert.h"
 #include "core/core.h"
-#include "core/hle/kernel/k_event.h"
 #include "core/hle/service/time/standard_local_system_clock_core.h"
 #include "core/hle/service/time/standard_network_system_clock_core.h"
 #include "core/hle/service/time/standard_user_system_clock_core.h"
@@ -17,10 +16,9 @@ StandardUserSystemClockCore::StandardUserSystemClockCore(
     : SystemClockCore(local_system_clock_core.GetSteadyClockCore()),
       local_system_clock_core{local_system_clock_core},
       network_system_clock_core{network_system_clock_core}, auto_correction_enabled{},
-      auto_correction_time{SteadyClockTimePoint::GetRandom()},
-      auto_correction_event{Kernel::KEvent::Create(
-          system.Kernel(), "StandardUserSystemClockCore:AutoCorrectionEvent")} {
-    auto_correction_event->Initialize();
+      auto_correction_time{SteadyClockTimePoint::GetRandom()}, auto_correction_event{
+                                                                   system.Kernel()} {
+    auto_correction_event.Initialize("StandardUserSystemClockCore:AutoCorrectionEvent");
 }
 
 ResultCode StandardUserSystemClockCore::SetAutomaticCorrectionEnabled(Core::System& system,
diff --git a/src/core/hle/service/time/standard_user_system_clock_core.h b/src/core/hle/service/time/standard_user_system_clock_core.h
index 5bc8bf5c2d..1bff8a5af8 100644
--- a/src/core/hle/service/time/standard_user_system_clock_core.h
+++ b/src/core/hle/service/time/standard_user_system_clock_core.h
@@ -4,6 +4,7 @@
 
 #pragma once
 
+#include "core/hle/kernel/k_event.h"
 #include "core/hle/service/time/clock_types.h"
 #include "core/hle/service/time/system_clock_core.h"
 
@@ -54,7 +55,7 @@ private:
     StandardNetworkSystemClockCore& network_system_clock_core;
     bool auto_correction_enabled{};
     SteadyClockTimePoint auto_correction_time;
-    std::shared_ptr<Kernel::KEvent> auto_correction_event;
+    Kernel::KEvent auto_correction_event;
 };
 
 } // namespace Service::Time::Clock
diff --git a/src/core/hle/service/vi/display/vi_display.cpp b/src/core/hle/service/vi/display/vi_display.cpp
index 9ffa713524..ebaacaa6ba 100644
--- a/src/core/hle/service/vi/display/vi_display.cpp
+++ b/src/core/hle/service/vi/display/vi_display.cpp
@@ -17,10 +17,9 @@
 
 namespace Service::VI {
 
-Display::Display(u64 id, std::string name, Core::System& system) : id{id}, name{std::move(name)} {
-    auto& kernel = system.Kernel();
-    vsync_event = Kernel::KEvent::Create(kernel, fmt::format("Display VSync Event {}", id));
-    vsync_event->Initialize();
+Display::Display(u64 id, std::string name, Core::System& system)
+    : id{id}, name{std::move(name)}, vsync_event{system.Kernel()} {
+    vsync_event.Initialize(fmt::format("Display VSync Event {}", id));
 }
 
 Display::~Display() = default;
@@ -34,11 +33,11 @@ const Layer& Display::GetLayer(std::size_t index) const {
 }
 
 std::shared_ptr<Kernel::KReadableEvent> Display::GetVSyncEvent() const {
-    return SharedFrom(vsync_event->GetReadableEvent());
+    return vsync_event.GetReadableEvent();
 }
 
 void Display::SignalVSyncEvent() {
-    vsync_event->GetWritableEvent()->Signal();
+    vsync_event.GetWritableEvent()->Signal();
 }
 
 void Display::CreateLayer(u64 layer_id, NVFlinger::BufferQueue& buffer_queue) {
diff --git a/src/core/hle/service/vi/display/vi_display.h b/src/core/hle/service/vi/display/vi_display.h
index 8340059ded..e990d6809f 100644
--- a/src/core/hle/service/vi/display/vi_display.h
+++ b/src/core/hle/service/vi/display/vi_display.h
@@ -8,6 +8,7 @@
 #include <string>
 #include <vector>
 
+#include "common/common_funcs.h"
 #include "common/common_types.h"
 
 namespace Kernel {
@@ -24,6 +25,9 @@ class Layer;
 
 /// Represents a single display type
 class Display {
+    NON_COPYABLE(Display);
+    NON_MOVEABLE(Display);
+
 public:
     /// Constructs a display with a given unique ID and name.
     ///
@@ -33,12 +37,6 @@ public:
     Display(u64 id, std::string name, Core::System& system);
     ~Display();
 
-    Display(const Display&) = delete;
-    Display& operator=(const Display&) = delete;
-
-    Display(Display&&) = default;
-    Display& operator=(Display&&) = default;
-
     /// Gets the unique ID assigned to this display.
     u64 GetID() const {
         return id;
@@ -102,7 +100,7 @@ private:
     std::string name;
 
     std::vector<std::shared_ptr<Layer>> layers;
-    std::shared_ptr<Kernel::KEvent> vsync_event;
+    Kernel::KEvent vsync_event;
 };
 
 } // namespace Service::VI