Kaynağa Gözat

feat: support manual memory cleanup when running in debug mode

dongchengjie 11 ay önce
ebeveyn
işleme
8e78b9e405

+ 18 - 17
src/components/layout/layout-traffic.tsx

@@ -14,12 +14,15 @@ import parseTraffic from "@/utils/parse-traffic";
 import useSWRSubscription from "swr/subscription";
 import { createSockette } from "@/utils/websocket";
 import { useTranslation } from "react-i18next";
+import { isDebugEnabled, gc } from "@/services/api";
 
 interface MemoryUsage {
   inuse: number;
   oslimit?: number;
 }
 
+const isDebug = await isDebugEnabled();
+
 // setup the traffic
 export const LayoutTraffic = () => {
   const { t } = useTranslation();
@@ -112,6 +115,11 @@ export const LayoutTraffic = () => {
   const [down, downUnit] = parseTraffic(traffic.down);
   const [inuse, inuseUnit] = parseTraffic(memory.inuse);
 
+  const boxStyle: any = {
+    display: "flex",
+    alignItems: "center",
+    whiteSpace: "nowrap",
+  };
   const iconStyle: any = {
     sx: { mr: "8px", fontSize: 16 },
   };
@@ -140,12 +148,7 @@ export const LayoutTraffic = () => {
       )}
 
       <Box display="flex" flexDirection="column" gap={0.75}>
-        <Box
-          display="flex"
-          alignItems="center"
-          whiteSpace="nowrap"
-          title={t("Upload Speed")}
-        >
+        <Box title={t("Upload Speed")} {...boxStyle}>
           <ArrowUpward
             {...iconStyle}
             color={+up > 0 ? "secondary" : "disabled"}
@@ -156,12 +159,7 @@ export const LayoutTraffic = () => {
           <Typography {...unitStyle}>{upUnit}/s</Typography>
         </Box>
 
-        <Box
-          display="flex"
-          alignItems="center"
-          whiteSpace="nowrap"
-          title={t("Download Speed")}
-        >
+        <Box title={t("Download Speed")} {...boxStyle}>
           <ArrowDownward
             {...iconStyle}
             color={+down > 0 ? "primary" : "disabled"}
@@ -174,12 +172,15 @@ export const LayoutTraffic = () => {
 
         {displayMemory && (
           <Box
-            display="flex"
-            alignItems="center"
-            whiteSpace="nowrap"
-            title={t("Memory Usage")}
+            title={t(isDebug ? "Memory Cleanup" : "Memory Usage")}
+            {...boxStyle}
+            sx={{ cursor: isDebug ? "pointer" : "auto" }}
+            color={isDebug ? "success.main" : "disabled"}
+            onClick={async () => {
+              isDebug && (await gc());
+            }}
           >
-            <MemoryOutlined {...iconStyle} color="disabled" />
+            <MemoryOutlined {...iconStyle} />
             <Typography {...valStyle}>{inuse}</Typography>
             <Typography {...unitStyle}>{inuseUnit}</Typography>
           </Box>

+ 1 - 0
src/locales/en.json

@@ -204,6 +204,7 @@
   "Layout Setting": "Layout Setting",
   "Traffic Graph": "Traffic Graph",
   "Memory Usage": "Memory Usage",
+  "Memory Cleanup": "Tap to clean up memory",
   "Proxy Group Icon": "Proxy Group Icon",
   "Menu Icon": "Menu Icon",
   "Monochrome": "Monochrome",

+ 1 - 0
src/locales/fa.json

@@ -204,6 +204,7 @@
   "Layout Setting": "تنظیمات چیدمان",
   "Traffic Graph": "نمودار ترافیک",
   "Memory Usage": "استفاده از حافظه",
+  "Memory Cleanup": "برای پاکسازی حافظه ضربه بزنید",
   "Proxy Group Icon": "آیکون گروه پراکسی",
   "Menu Icon": "آیکون منو",
   "Monochrome": "تک رنگ",

+ 1 - 0
src/locales/ru.json

@@ -204,6 +204,7 @@
   "Layout Setting": "Настройки раскладки",
   "Traffic Graph": "График трафика",
   "Memory Usage": "Использование памяти",
+  "Memory Cleanup": "Нажмите, чтобы очистить память",
   "Proxy Group Icon": "Иконка Группы прокси",
   "Menu Icon": "Иконка меню",
   "Monochrome": "Монохромный",

+ 1 - 0
src/locales/zh.json

@@ -204,6 +204,7 @@
   "Layout Setting": "界面设置",
   "Traffic Graph": "流量图显",
   "Memory Usage": "内存使用",
+  "Memory Cleanup": "点击清理内存",
   "Proxy Group Icon": "代理组图标",
   "Menu Icon": "菜单图标",
   "Monochrome": "单色图标",

+ 21 - 0
src/services/api.ts

@@ -271,3 +271,24 @@ export const getGroupProxyDelays = async (
   );
   return result as any as Record<string, number>;
 };
+
+// Is debug enabled
+export const isDebugEnabled = async () => {
+  try {
+    const instance = await getAxios();
+    await instance.get("/debug/pprof");
+    return true;
+  } catch {
+    return false;
+  }
+};
+
+// GC
+export const gc = async () => {
+  try {
+    const instance = await getAxios();
+    await instance.put("/debug/gc");
+  } catch (error) {
+    console.error(`Error gcing: ${error}`);
+  }
+};