diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 7991f77cf0..8a8fa67091 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -22,7 +22,7 @@ KernelSystem::KernelSystem(u32 system_mode) {
 
     Kernel::MemoryInit(system_mode);
 
-    Kernel::ResourceLimitsInit();
+    resource_limits = std::make_unique<ResourceLimitList>(*this);
     Kernel::ThreadingInit();
     Kernel::TimersInit();
 
@@ -40,8 +40,15 @@ KernelSystem::~KernelSystem() {
     g_current_process = nullptr;
 
     Kernel::TimersShutdown();
-    Kernel::ResourceLimitsShutdown();
     Kernel::MemoryShutdown();
 }
 
+ResourceLimitList& KernelSystem::ResourceLimit() {
+    return *resource_limits;
+}
+
+const ResourceLimitList& KernelSystem::ResourceLimit() const {
+    return *resource_limits;
+}
+
 } // namespace Kernel
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 9ff8504e03..84a33d8e60 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -4,6 +4,7 @@
 
 #pragma once
 
+#include <memory>
 #include <string>
 #include <boost/smart_ptr/intrusive_ptr.hpp>
 #include "common/common_types.h"
@@ -23,6 +24,7 @@ class ClientPort;
 class ServerPort;
 class ClientSession;
 class ServerSession;
+class ResourceLimitList;
 
 enum class ResetType {
     OneShot,
@@ -116,6 +118,12 @@ public:
      */
     std::tuple<SharedPtr<ServerSession>, SharedPtr<ClientSession>> CreateSessionPair(
         const std::string& name = "Unknown", SharedPtr<ClientPort> client_port = nullptr);
+
+    ResourceLimitList& ResourceLimit();
+    const ResourceLimitList& ResourceLimit() const;
+
+private:
+    std::unique_ptr<ResourceLimitList> resource_limits;
 };
 
 } // namespace Kernel
diff --git a/src/core/hle/kernel/resource_limit.cpp b/src/core/hle/kernel/resource_limit.cpp
index ffe9f5108a..4aaf6be6b6 100644
--- a/src/core/hle/kernel/resource_limit.cpp
+++ b/src/core/hle/kernel/resource_limit.cpp
@@ -9,19 +9,17 @@
 
 namespace Kernel {
 
-static SharedPtr<ResourceLimit> resource_limits[4];
-
-ResourceLimit::ResourceLimit() {}
+ResourceLimit::ResourceLimit(KernelSystem& kernel) {}
 ResourceLimit::~ResourceLimit() {}
 
-SharedPtr<ResourceLimit> ResourceLimit::Create(std::string name) {
-    SharedPtr<ResourceLimit> resource_limit(new ResourceLimit);
+SharedPtr<ResourceLimit> ResourceLimit::Create(KernelSystem& kernel, std::string name) {
+    SharedPtr<ResourceLimit> resource_limit(new ResourceLimit(kernel));
 
     resource_limit->name = std::move(name);
     return resource_limit;
 }
 
-SharedPtr<ResourceLimit> ResourceLimit::GetForCategory(ResourceLimitCategory category) {
+SharedPtr<ResourceLimit> ResourceLimitList::GetForCategory(ResourceLimitCategory category) {
     switch (category) {
     case ResourceLimitCategory::APPLICATION:
     case ResourceLimitCategory::SYS_APPLET:
@@ -90,10 +88,10 @@ u32 ResourceLimit::GetMaxResourceValue(u32 resource) const {
     }
 }
 
-void ResourceLimitsInit() {
+ResourceLimitList::ResourceLimitList(KernelSystem& kernel) {
     // Create the four resource limits that the system uses
     // Create the APPLICATION resource limit
-    SharedPtr<ResourceLimit> resource_limit = ResourceLimit::Create("Applications");
+    SharedPtr<ResourceLimit> resource_limit = ResourceLimit::Create(kernel, "Applications");
     resource_limit->max_priority = 0x18;
     resource_limit->max_commit = 0x4000000;
     resource_limit->max_threads = 0x20;
@@ -107,7 +105,7 @@ void ResourceLimitsInit() {
     resource_limits[static_cast<u8>(ResourceLimitCategory::APPLICATION)] = resource_limit;
 
     // Create the SYS_APPLET resource limit
-    resource_limit = ResourceLimit::Create("System Applets");
+    resource_limit = ResourceLimit::Create(kernel, "System Applets");
     resource_limit->max_priority = 0x4;
     resource_limit->max_commit = 0x5E00000;
     resource_limit->max_threads = 0x1D;
@@ -121,7 +119,7 @@ void ResourceLimitsInit() {
     resource_limits[static_cast<u8>(ResourceLimitCategory::SYS_APPLET)] = resource_limit;
 
     // Create the LIB_APPLET resource limit
-    resource_limit = ResourceLimit::Create("Library Applets");
+    resource_limit = ResourceLimit::Create(kernel, "Library Applets");
     resource_limit->max_priority = 0x4;
     resource_limit->max_commit = 0x600000;
     resource_limit->max_threads = 0xE;
@@ -135,7 +133,7 @@ void ResourceLimitsInit() {
     resource_limits[static_cast<u8>(ResourceLimitCategory::LIB_APPLET)] = resource_limit;
 
     // Create the OTHER resource limit
-    resource_limit = ResourceLimit::Create("Others");
+    resource_limit = ResourceLimit::Create(kernel, "Others");
     resource_limit->max_priority = 0x4;
     resource_limit->max_commit = 0x2180000;
     resource_limit->max_threads = 0xE1;
@@ -149,6 +147,6 @@ void ResourceLimitsInit() {
     resource_limits[static_cast<u8>(ResourceLimitCategory::OTHER)] = resource_limit;
 }
 
-void ResourceLimitsShutdown() {}
+ResourceLimitList::~ResourceLimitList() = default;
 
 } // namespace Kernel
diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h
index 7d6e8611db..3b8b79d0c5 100644
--- a/src/core/hle/kernel/resource_limit.h
+++ b/src/core/hle/kernel/resource_limit.h
@@ -4,6 +4,7 @@
 
 #pragma once
 
+#include <array>
 #include "common/common_types.h"
 #include "core/hle/kernel/object.h"
 
@@ -34,14 +35,7 @@ public:
     /**
      * Creates a resource limit object.
      */
-    static SharedPtr<ResourceLimit> Create(std::string name = "Unknown");
-
-    /**
-     * Retrieves the resource limit associated with the specified resource limit category.
-     * @param category The resource limit category
-     * @returns The resource limit associated with the category
-     */
-    static SharedPtr<ResourceLimit> GetForCategory(ResourceLimitCategory category);
+    static SharedPtr<ResourceLimit> Create(KernelSystem& kernel, std::string name = "Unknown");
 
     std::string GetTypeName() const override {
         return "ResourceLimit";
@@ -113,14 +107,24 @@ public:
     s32 current_cpu_time = 0;
 
 private:
-    ResourceLimit();
+    explicit ResourceLimit(KernelSystem& kernel);
     ~ResourceLimit() override;
 };
 
-/// Initializes the resource limits
-void ResourceLimitsInit();
+class ResourceLimitList {
+public:
+    explicit ResourceLimitList(KernelSystem& kernel);
+    ~ResourceLimitList();
 
-// Destroys the resource limits
-void ResourceLimitsShutdown();
+    /**
+     * Retrieves the resource limit associated with the specified resource limit category.
+     * @param category The resource limit category
+     * @returns The resource limit associated with the category
+     */
+    SharedPtr<ResourceLimit> GetForCategory(ResourceLimitCategory category);
+
+private:
+    std::array<SharedPtr<ResourceLimit>, 4> resource_limits;
+};
 
 } // namespace Kernel
diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp
index 486270a59e..1b3905b02e 100644
--- a/src/core/loader/3dsx.cpp
+++ b/src/core/loader/3dsx.cpp
@@ -272,8 +272,8 @@ ResultStatus AppLoader_THREEDSX::Load(Kernel::SharedPtr<Kernel::Process>& proces
     process->address_mappings = default_address_mappings;
 
     // Attach the default resource limit (APPLICATION) to the process
-    process->resource_limit =
-        Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
+    process->resource_limit = Core::System::GetInstance().Kernel().ResourceLimit().GetForCategory(
+        Kernel::ResourceLimitCategory::APPLICATION);
 
     process->Run(48, Kernel::DEFAULT_STACK_SIZE);
 
diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp
index 86abd77639..26470ff9d5 100644
--- a/src/core/loader/elf.cpp
+++ b/src/core/loader/elf.cpp
@@ -401,8 +401,8 @@ ResultStatus AppLoader_ELF::Load(Kernel::SharedPtr<Kernel::Process>& process) {
     process->address_mappings = default_address_mappings;
 
     // Attach the default resource limit (APPLICATION) to the process
-    process->resource_limit =
-        Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
+    process->resource_limit = Core::System::GetInstance().Kernel().ResourceLimit().GetForCategory(
+        Kernel::ResourceLimitCategory::APPLICATION);
 
     process->Run(48, Kernel::DEFAULT_STACK_SIZE);
 
diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp
index 10260591a2..34f49663a7 100644
--- a/src/core/loader/ncch.cpp
+++ b/src/core/loader/ncch.cpp
@@ -108,8 +108,9 @@ ResultStatus AppLoader_NCCH::LoadExec(Kernel::SharedPtr<Kernel::Process>& proces
 
         // Attach a resource limit to the process based on the resource limit category
         process->resource_limit =
-            Kernel::ResourceLimit::GetForCategory(static_cast<Kernel::ResourceLimitCategory>(
-                overlay_ncch->exheader_header.arm11_system_local_caps.resource_limit_category));
+            Core::System::GetInstance().Kernel().ResourceLimit().GetForCategory(
+                static_cast<Kernel::ResourceLimitCategory>(
+                    overlay_ncch->exheader_header.arm11_system_local_caps.resource_limit_category));
 
         // Set the default CPU core for this process
         process->ideal_processor =