<properties>
<java.version>11</java.version>
<!-- 2.x 최신버전에서 validation이 강화되어, 버전을 낮춰서 테스트 진행하는 것으로 보임. JJH -->
<h2.version>1.4.196</h2.version>
</properties>
G1에서 결국 Memory 가 Full 단계(To-space exhausted) 까지 가야 Full GC가 발생함.
(원래 Full GC를 피하기 위해서 이런 저런 GC가 나옴)
사용자측에서 Memory에 민감해서, 메모리가 40%만 넘어도 민감해 함.
SpringBoot 또는 관련 라이브러리 문제로 Full GC에서만 메모리가 해제되고, 나머지 GC에서는 HashMap 관련 객체가 해제되지 않는 듯 함. (=> 객체를 조사해 보니, bytes는 oracle 데이터, map은 jmx에서 사용, 조정 가능한게 별로 없음)
서버 부하가 심하지 않으면, 스케줄러를 이용해서 애플리케이션의 유휴 시간대에 강제로 System.gc() 로 Full GC를 발생하는 것도 방법인 듯. => 결국, 스케줄러에서 새벽에 임계치를 넘으면 초기화 하기로 함.
package test;
import java.util.*;
public class GCTest22 {
public static void main(String[] args) throws InterruptedException {
final int newMapCount = 1000;
List<Map> list = new ArrayList<>();
Map<String, String> newMap = new HashMap<>();
for (int i = 0; true; i++) {
if (i > 0 && i % (100 * newMapCount) == 0) {
long used = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
System.out.println(getStringWithGreen(String.format(formatMemory, i, used)));
Thread.sleep(1000);
}
if (i > 0 && i % newMapCount == 0) {
newMap = new HashMap<>();
}
String newStr1 = new String(i + "_abcdefghijklmnopqrstuvwxyz1,");
newMap.put(i + "a", newStr1);
if (i > newMapCount && (i / newMapCount) % 5 == 0) {
list.add(newMap);
}
if (i > 0 && i % (3000 * newMapCount) == 0) {
System.gc();
}
}
}
private static String formatMemory = "테스트 %,d, 메모리사용량: %,d";
private static String formatGreenColor = "\u001B[32m%s\u001B[0m";
private static String getStringWithGreen(String s) {
return String.format(formatGreenColor, s);
}
}