1. GC 설명이 잘 정리된 자료

https://devfunny.tistory.com/681

 

JVM GC (Garbage Collection) 에 대한 정리

가비지 컬렉션 (Garbage Collection) 유효하지 않은 메모리(Garbage)를 자동으로 제거해주는 작업이다. Java Appliation은 JVM(Java Virtual Machine)위에서 구동되는데, JVM의 기능 중 더이상 사용하지 않는 객체를

devfunny.tistory.com

 

2. G1 GC에서 Full GC는 잘 안일어난다.

https://stackoverflow.com/questions/69379494/full-gc-is-not-kicking-in-for-g1-gc-in-java-11-what-could-be-the-reasons

 

Full GC is not kicking in for G1 GC in Java 11. What could be the reasons?

The JVM arguments are as follows: -Xms20g -Xmx20g -XX:MaxGCPauseMillis=10000 -XX:G1ReservePercent=30 -Duser.timezone=UTC The only thing in logs are Pause Young (Normal) (G1 Evacuation Pause) Pause

stackoverflow.com

 

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);
	}
}

 

-verbose:gc -Xmx1024m

실행 옵션

 

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
	PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
	"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<settings>
		<setting name="cacheEnabled" value="false"/>
		<setting name="localCacheScope" value="STATEMENT" /> <!-- STATEMENT / SESSION -->
	</settings>
</configuration>

 

MyBatis에서 localCacheScope(SESSION) 캐시가 해제되지 않아, STATEMENT로 변경했는데 메모리 증가가 둔화는 되었으나 여전히 해당 어플리케이션에서 많은 트랜잭션이 몰리면 메모리 증가 현상이 보임.

=> 이상 없음

 

 

728x90

+ Recent posts