13af6ab5fSopenharmony_ci/*
23af6ab5fSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
33af6ab5fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43af6ab5fSopenharmony_ci * you may not use this file except in compliance with the License.
53af6ab5fSopenharmony_ci * You may obtain a copy of the License at
63af6ab5fSopenharmony_ci *
73af6ab5fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
83af6ab5fSopenharmony_ci *
93af6ab5fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103af6ab5fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113af6ab5fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123af6ab5fSopenharmony_ci * See the License for the specific language governing permissions and
133af6ab5fSopenharmony_ci * limitations under the License.
143af6ab5fSopenharmony_ci */
153af6ab5fSopenharmony_ci
163af6ab5fSopenharmony_ciexport class MemoryUtils {
173af6ab5fSopenharmony_ci  private static baseMemorySize: number | undefined = undefined; 
183af6ab5fSopenharmony_ci  private static allowGC: boolean = typeof global.gc === 'function';
193af6ab5fSopenharmony_ci  private static MIN_GC_THRESHOLD: number = 64 * 1024 * 1024; // 64MB
203af6ab5fSopenharmony_ci  private static memoryGCThreshold: number = MemoryUtils.MIN_GC_THRESHOLD;
213af6ab5fSopenharmony_ci  public static GC_THRESHOLD_RATIO: number = 0.3;
223af6ab5fSopenharmony_ci  
233af6ab5fSopenharmony_ci  /**
243af6ab5fSopenharmony_ci   * Try garbage collection if obfuscaction starts or the memory usage exceeds MEMORY_BASELINE.
253af6ab5fSopenharmony_ci   */
263af6ab5fSopenharmony_ci  public static tryGC(): void {
273af6ab5fSopenharmony_ci    if (!MemoryUtils.allowGC) {
283af6ab5fSopenharmony_ci      return;
293af6ab5fSopenharmony_ci    }
303af6ab5fSopenharmony_ci  
313af6ab5fSopenharmony_ci    const currentMemory = process.memoryUsage().heapUsed;
323af6ab5fSopenharmony_ci    if (MemoryUtils.baseMemorySize === undefined || (currentMemory - MemoryUtils.baseMemorySize > MemoryUtils.memoryGCThreshold)) {
333af6ab5fSopenharmony_ci      global.gc();
343af6ab5fSopenharmony_ci      MemoryUtils.updateBaseMemory();
353af6ab5fSopenharmony_ci      return;
363af6ab5fSopenharmony_ci    }
373af6ab5fSopenharmony_ci
383af6ab5fSopenharmony_ci    if (MemoryUtils.baseMemorySize > currentMemory) {
393af6ab5fSopenharmony_ci      MemoryUtils.updateBaseMemory(currentMemory);
403af6ab5fSopenharmony_ci      return;
413af6ab5fSopenharmony_ci    }
423af6ab5fSopenharmony_ci  }
433af6ab5fSopenharmony_ci
443af6ab5fSopenharmony_ci  // For ut only
453af6ab5fSopenharmony_ci  public static setGC(allowGC: boolean): void {
463af6ab5fSopenharmony_ci    MemoryUtils.allowGC = allowGC;
473af6ab5fSopenharmony_ci  }
483af6ab5fSopenharmony_ci
493af6ab5fSopenharmony_ci  // For ut only
503af6ab5fSopenharmony_ci  public static getBaseMemorySize(): number {
513af6ab5fSopenharmony_ci    return MemoryUtils.baseMemorySize;
523af6ab5fSopenharmony_ci  }
533af6ab5fSopenharmony_ci
543af6ab5fSopenharmony_ci  // For ut only
553af6ab5fSopenharmony_ci  public static setBaseMemorySize(baseMemorySize: number | undefined): void {
563af6ab5fSopenharmony_ci    MemoryUtils.baseMemorySize = baseMemorySize;
573af6ab5fSopenharmony_ci  }
583af6ab5fSopenharmony_ci
593af6ab5fSopenharmony_ci  // For ut only
603af6ab5fSopenharmony_ci  public static setMinGCThreshold(threshold: number): void {
613af6ab5fSopenharmony_ci    MemoryUtils.MIN_GC_THRESHOLD = threshold;
623af6ab5fSopenharmony_ci  }
633af6ab5fSopenharmony_ci
643af6ab5fSopenharmony_ci  // For ut only
653af6ab5fSopenharmony_ci  public static getMinGCThreshold(): number {
663af6ab5fSopenharmony_ci    return MemoryUtils.MIN_GC_THRESHOLD;
673af6ab5fSopenharmony_ci  }
683af6ab5fSopenharmony_ci
693af6ab5fSopenharmony_ci  // For ut only
703af6ab5fSopenharmony_ci  public static getGCThreshold(): number {
713af6ab5fSopenharmony_ci    return MemoryUtils.memoryGCThreshold;
723af6ab5fSopenharmony_ci  }
733af6ab5fSopenharmony_ci
743af6ab5fSopenharmony_ci  public static updateBaseMemory(currentMemory?: number): void {
753af6ab5fSopenharmony_ci    currentMemory = currentMemory ?? process.memoryUsage().heapUsed;
763af6ab5fSopenharmony_ci    const targetGCThreshold: number = currentMemory * MemoryUtils.GC_THRESHOLD_RATIO;
773af6ab5fSopenharmony_ci    MemoryUtils.memoryGCThreshold = Math.max(targetGCThreshold, MemoryUtils.MIN_GC_THRESHOLD);
783af6ab5fSopenharmony_ci    MemoryUtils.baseMemorySize = currentMemory;
793af6ab5fSopenharmony_ci  }
803af6ab5fSopenharmony_ci}