1/* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16export class MemoryUtils { 17 private static baseMemorySize: number | undefined = undefined; 18 private static allowGC: boolean = typeof global.gc === 'function'; 19 private static MIN_GC_THRESHOLD: number = 64 * 1024 * 1024; // 64MB 20 private static memoryGCThreshold: number = MemoryUtils.MIN_GC_THRESHOLD; 21 public static GC_THRESHOLD_RATIO: number = 0.3; 22 23 /** 24 * Try garbage collection if obfuscaction starts or the memory usage exceeds MEMORY_BASELINE. 25 */ 26 public static tryGC(): void { 27 if (!MemoryUtils.allowGC) { 28 return; 29 } 30 31 const currentMemory = process.memoryUsage().heapUsed; 32 if (MemoryUtils.baseMemorySize === undefined || (currentMemory - MemoryUtils.baseMemorySize > MemoryUtils.memoryGCThreshold)) { 33 global.gc(); 34 MemoryUtils.updateBaseMemory(); 35 return; 36 } 37 38 if (MemoryUtils.baseMemorySize > currentMemory) { 39 MemoryUtils.updateBaseMemory(currentMemory); 40 return; 41 } 42 } 43 44 // For ut only 45 public static setGC(allowGC: boolean): void { 46 MemoryUtils.allowGC = allowGC; 47 } 48 49 // For ut only 50 public static getBaseMemorySize(): number { 51 return MemoryUtils.baseMemorySize; 52 } 53 54 // For ut only 55 public static setBaseMemorySize(baseMemorySize: number | undefined): void { 56 MemoryUtils.baseMemorySize = baseMemorySize; 57 } 58 59 // For ut only 60 public static setMinGCThreshold(threshold: number): void { 61 MemoryUtils.MIN_GC_THRESHOLD = threshold; 62 } 63 64 // For ut only 65 public static getMinGCThreshold(): number { 66 return MemoryUtils.MIN_GC_THRESHOLD; 67 } 68 69 // For ut only 70 public static getGCThreshold(): number { 71 return MemoryUtils.memoryGCThreshold; 72 } 73 74 public static updateBaseMemory(currentMemory?: number): void { 75 currentMemory = currentMemory ?? process.memoryUsage().heapUsed; 76 const targetGCThreshold: number = currentMemory * MemoryUtils.GC_THRESHOLD_RATIO; 77 MemoryUtils.memoryGCThreshold = Math.max(targetGCThreshold, MemoryUtils.MIN_GC_THRESHOLD); 78 MemoryUtils.baseMemorySize = currentMemory; 79 } 80}