diff --git a/Ryujinx.Common/SystemInfo.cs b/Ryujinx.Common/SystemInfo.cs
deleted file mode 100644
index dbe026172..000000000
--- a/Ryujinx.Common/SystemInfo.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-using System;
-using System.IO;
-using System.Linq;
-using System.Management;
-using System.Runtime.InteropServices;
-
-namespace Ryujinx.Common
-{
-    public static class SystemInfo
-    {
-        public static string OsDescription { get; private set; }
-        public static string CpuName       { get; private set; }
-        public static string RamSize       { get; private set; }
-
-        static SystemInfo()
-        {
-            OsDescription = $"{RuntimeInformation.OSDescription} ({RuntimeInformation.OSArchitecture})";
-            CpuName       = "Unknown";
-            RamSize       = "Unknown";
-
-            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
-            {
-                foreach (ManagementBaseObject mObject in new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_Processor").Get())
-                {
-                    CpuName = mObject["Name"].ToString();
-                }
-
-                foreach (ManagementBaseObject mObject in new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_OperatingSystem").Get())
-                {
-                    RamSize = $"{Math.Round(double.Parse(mObject["TotalVisibleMemorySize"].ToString()) / 1024, 0)} MB";
-                }
-            }
-
-            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
-            {
-                CpuName = File.ReadAllLines("/proc/cpuinfo").Where(line => line.StartsWith("model name")).ToList()[0].Split(":")[1].Trim();
-                RamSize = $"{Math.Round(double.Parse(File.ReadAllLines("/proc/meminfo")[0].Split(":")[1].Trim().Split(" ")[0]) / 1024, 0)} MB";
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Common/SystemInfo/LinuxSystemInfo.cs b/Ryujinx.Common/SystemInfo/LinuxSystemInfo.cs
new file mode 100644
index 000000000..bd3ee57a5
--- /dev/null
+++ b/Ryujinx.Common/SystemInfo/LinuxSystemInfo.cs
@@ -0,0 +1,17 @@
+using System.IO;
+using System.Linq;
+
+namespace Ryujinx.Common.SystemInfo
+{
+    internal class LinuxSysteminfo : SystemInfo
+    {
+        public override string CpuName { get; }
+        public override ulong RamSize { get; }
+
+        public LinuxSysteminfo()
+        {
+            CpuName = File.ReadAllLines("/proc/cpuinfo").Where(line => line.StartsWith("model name")).ToList()[0].Split(":")[1].Trim();
+            RamSize = ulong.Parse(File.ReadAllLines("/proc/meminfo")[0].Split(":")[1].Trim().Split(" ")[0]) * 1024;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Common/SystemInfo/MacOSSysteminfo.cs b/Ryujinx.Common/SystemInfo/MacOSSysteminfo.cs
new file mode 100644
index 000000000..167c96dbf
--- /dev/null
+++ b/Ryujinx.Common/SystemInfo/MacOSSysteminfo.cs
@@ -0,0 +1,97 @@
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Text;
+using Ryujinx.Common.Logging;
+
+namespace Ryujinx.Common.SystemInfo
+{
+    internal class MacOSSysteminfo : SystemInfo
+    {
+        public override string CpuName { get; }
+        public override ulong RamSize { get; }
+
+        [DllImport("libSystem.dylib", CharSet = CharSet.Ansi, SetLastError = true)]
+        private static extern int sysctlbyname(string name, IntPtr oldValue, ref ulong oldSize, IntPtr newValue, ulong newValueSize);
+
+        private static int sysctlbyname(string name, IntPtr oldValue, ref ulong oldSize)
+        {
+            if (sysctlbyname(name, oldValue, ref oldSize, IntPtr.Zero, 0) == -1)
+            {
+                return Marshal.GetLastWin32Error();
+            }
+
+            return 0;
+        }
+
+        private static int sysctlbyname<T>(string name, ref T oldValue)
+        {
+            unsafe
+            {
+                ulong oldValueSize = (ulong)Unsafe.SizeOf<T>();
+
+                return sysctlbyname(name, (IntPtr)Unsafe.AsPointer(ref oldValue), ref oldValueSize);
+            }
+        }
+
+        private static int sysctlbyname(string name, out string oldValue)
+        {
+            oldValue = default;
+
+            ulong strSize = 0;
+
+            int res = sysctlbyname(name, IntPtr.Zero, ref strSize);
+
+            if (res == 0)
+            {
+                byte[] rawData = new byte[strSize];
+
+                unsafe
+                {
+                    fixed (byte* rawDataPtr = rawData)
+                    {
+                        res = sysctlbyname(name, (IntPtr)rawDataPtr, ref strSize);
+                    }
+
+                    if (res == 0)
+                    {
+                        oldValue = Encoding.ASCII.GetString(rawData);
+                    }
+                }
+            }
+
+            return res;
+        }
+
+        public MacOSSysteminfo()
+        {
+            ulong ramSize = 0;
+
+            int res = sysctlbyname("hw.memsize", ref ramSize);
+
+            if (res == 0)
+            {
+                RamSize = ramSize;
+            }
+            else
+            {
+                Logger.PrintError(LogClass.Application, $"Cannot get memory size, sysctlbyname error: {res}");
+
+                RamSize = 0;
+            }
+
+            res = sysctlbyname("machdep.cpu.brand_string", out string cpuName);
+
+            if (res == 0)
+            {
+                CpuName = cpuName;
+            }
+            else
+            {
+                Logger.PrintError(LogClass.Application, $"Cannot get CPU name, sysctlbyname error: {res}");
+
+                CpuName = "Unknown";
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Common/SystemInfo/SystemInfo.cs b/Ryujinx.Common/SystemInfo/SystemInfo.cs
new file mode 100644
index 000000000..9ab1419c8
--- /dev/null
+++ b/Ryujinx.Common/SystemInfo/SystemInfo.cs
@@ -0,0 +1,46 @@
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.Common.SystemInfo
+{
+    public class SystemInfo
+    {
+        public virtual string OsDescription => $"{RuntimeInformation.OSDescription} ({RuntimeInformation.OSArchitecture})";
+        public virtual string CpuName => "Unknown";
+        public virtual ulong RamSize => 0;
+
+        public string RamSizeInMB
+        {
+            get
+            {
+                if (RamSize == 0)
+                {
+                    return "Unknown";
+                }
+
+                return $"{RamSize / 1024 / 1024} MB";
+            }
+        }
+
+        public static SystemInfo Instance { get; }
+
+        static SystemInfo()
+        {
+            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+            {
+                Instance = new WindowsSysteminfo();
+            }
+            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+            {
+                Instance = new LinuxSysteminfo();
+            }
+            else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+            {
+                Instance = new MacOSSysteminfo();
+            }
+            else
+            {
+                Instance = new SystemInfo();
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Common/SystemInfo/WindowsSystemInfo.cs b/Ryujinx.Common/SystemInfo/WindowsSystemInfo.cs
new file mode 100644
index 000000000..1d4e61faf
--- /dev/null
+++ b/Ryujinx.Common/SystemInfo/WindowsSystemInfo.cs
@@ -0,0 +1,23 @@
+using System.Management;
+
+namespace Ryujinx.Common.SystemInfo
+{
+    internal class WindowsSysteminfo : SystemInfo
+    {
+        public override string CpuName { get; }
+        public override ulong RamSize { get; }
+
+        public WindowsSysteminfo()
+        {
+            foreach (ManagementBaseObject mObject in new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_Processor").Get())
+            {
+                CpuName = mObject["Name"].ToString();
+            }
+
+            foreach (ManagementBaseObject mObject in new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_OperatingSystem").Get())
+            {
+                RamSize = ulong.Parse(mObject["TotalVisibleMemorySize"].ToString()) * 1024;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx/Program.cs b/Ryujinx/Program.cs
index 2a906b82a..45876da8d 100644
--- a/Ryujinx/Program.cs
+++ b/Ryujinx/Program.cs
@@ -1,6 +1,6 @@
 using Gtk;
-using Ryujinx.Common;
 using Ryujinx.Common.Logging;
+using Ryujinx.Common.SystemInfo;
 using Ryujinx.Configuration;
 using Ryujinx.Debugger.Profiler;
 using Ryujinx.Ui;
@@ -45,9 +45,9 @@ namespace Ryujinx
 
             Logger.PrintInfo(LogClass.Application, $"Ryujinx Version: {Version}");
 
-            Logger.PrintInfo(LogClass.Application, $"Operating System: {SystemInfo.OsDescription}");
-            Logger.PrintInfo(LogClass.Application, $"CPU: {SystemInfo.CpuName}");
-            Logger.PrintInfo(LogClass.Application, $"Total RAM: {SystemInfo.RamSize}");
+            Logger.PrintInfo(LogClass.Application, $"Operating System: {SystemInfo.Instance.OsDescription}");
+            Logger.PrintInfo(LogClass.Application, $"CPU: {SystemInfo.Instance.CpuName}");
+            Logger.PrintInfo(LogClass.Application, $"Total RAM: {SystemInfo.Instance.RamSizeInMB}");
 
             string localConfigurationPath  = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json");
             string globalBasePath          = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Ryujinx");