← 목록

EC2 메모리 사용률 82% → 86% 지속 상승, Java 프로세스 분석 및 대응

t3.large EC2 인스턴스에서 메모리 사용률이 비정상적으로 높아진 원인을 분석하고, Java 프로세스별 메모리 점유를 추적한 트러블슈팅 기록

2025-09-01AWSEC2TroubleshootingMemoryJavaMonitoring

문제 인식

운영 중인 EC2 인스턴스(t3.large)에서 CloudWatch Agent 기반 메모리 모니터링 중 82.4% 의 높은 메모리 사용률을 확인했다.

DB 서버도 아닌 애플리케이션 서버에서 이 정도 메모리 사용률은 비정상적이었고, 이 상태가 지속되면 메모리 누수나 스왑 의존으로 인한 성능 저하가 우려되었다.


서버 사양 확인

항목값
인스턴스 타입t3.large
vCPU2개
메모리8 GiB
네트워크 성능Moderate
EBS 최적화지원 (최대 2,250 Mbps)
CPU 모델크레딧 기반 버스트

t3.large는 간헐적 부하에 적합한 버스트 가능 인스턴스로, 웹 서버나 마이크로서비스 운영에 주로 사용된다. 8GB 메모리에서 82%를 상시 점유하는 것은 정상적인 운영 패턴이 아니었다.


메모리 상태 분석 (free -m)

$ free -m
              total    used    free    shared  buff/cache  available
Mem:          7719     6359     142      64       1216        996
Swap:        10239     1719    8520

물리 메모리

항목값비고
Total7,719 MB (~7.7 GB)
Used6,359 MB (~6.4 GB)앱 + 캐시/버퍼 포함
Free142 MB (~0.14 GB)실질적으로 여유 없음
Buff/Cache1,216 MB (~1.2 GB)Linux 캐시 (필요 시 해제 가능)
Available996 MB (~1 GB)실제 사용 가능한 메모리

t3.large 메모리 구성

스왑 메모리

항목값
Total10,239 MB (~10.2 GB)
Used1,719 MB (~1.7 GB)
Free8,520 MB (~8.5 GB)

스왑 사용량이 1.7GB에 달한다는 것은 물리 메모리가 충분하지 않아 디스크 기반 스왑에 의존하고 있다는 의미다. 스왑 I/O는 물리 메모리 대비 수십~수백 배 느리므로 성능 저하의 직접적 원인이 된다.


프로세스별 메모리 점유 분석 (top / ps aux)

top 명령어와 ps aux | grep java 를 통해 메모리를 많이 사용하는 프로세스를 식별했다.

주요 프로세스 목록

순위PID프로세스메모리 사용률CPU 사용률메모리 크기
113596Java App (메인 서비스)47.9%14.0%~3.6 GB
216314Java App (Java 1.8)9.7%--
325611Java App (에이전트)7.8%0.3%~616 MB
47331Partner Agent (OpenJDK 18)3.3%--
58889Proxy Service (OpenJDK 18)2.7%--
62748CloudWatch Agent0.4%0.7%~31 MB

핵심 원인: PID 13596 Java 프로세스 하나가 시스템 메모리의 절반(47.9%) 을 차지하고 있었다. 여러 Java 프로세스가 동시에 실행되면서 총 메모리 사용률이 82%를 넘긴 상황이었다.


PID 16314 실행 파일 확인

$ sudo ls -l /proc/16314/exe
lrwxrwxrwx 1 root root 0 Oct 14 00:34 /proc/16314/exe -> /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.322.b06-1.el7_9.x86_64/jre/bin/java

해당 프로세스는 시스템에 설치된 OpenJDK 1.8 런타임으로 실행된 Java 프로세스였다.


나머지 1GB의 행방 (cat /proc/meminfo)

Java 프로세스들의 합산 메모리와 buff/cache를 제외하고도 약 1GB가 어디에 사용되는지 확인했다.

cat /proc/meminfo 분석 결과:

이 1GB는 커널과 시스템 레벨에서 사용하는 메모리로, 애플리케이션이 직접 제어할 수 없는 영역이다.


모니터링 추이

초기 확인 시 82.4% 였던 메모리 사용률이 며칠 후 86.6% 로 상승했다.

일주일간 평균 메모리 사용량은 약 81.7%, 스왑 사용량은 1.7GB/10.2GB 수준을 유지했다.

메모리 사용률이 지속적으로 우상향하는 패턴은 메모리 누수 가능성을 시사한다.


분석 결과 및 대응 방향

원인 요약

  1. 다수의 Java 프로세스 동시 실행: 메인 서비스(47.9%) + 에이전트(7.8%) + 기타 Java 프로세스들이 8GB 메모리를 거의 소진
  2. 스왑 의존: 물리 메모리 부족으로 1.7GB 스왑 사용 중 → 디스크 I/O 기반이므로 성능 저하 유발
  3. Available 메모리 1GB 미만: 새로운 프로세스 실행이나 부하 증가 시 OOM 위험

대응 방안


마무리

단순히 "메모리 사용률이 높다"에서 끝나지 않고, free -m → top → ps aux → /proc/meminfo 순서로 단계적으로 원인을 추적했다.

인프라 운영에서 메모리 이슈는 즉각적인 장애로 이어지지 않더라도, 스왑 의존 → 성능 저하 → OOM Kill 순서로 점진적으로 악화되기 때문에 조기 발견과 대응이 중요하다.


배운 점

메모리 사용률이 높다는 사실만으로는 아무것도 결정할 수 없다. buff/cache까지 합쳐진 숫자인지, 실제로 프로세스가 점유한 양인지에 따라 대응이 완전히 달라지기 때문이다. 지표를 볼 때 그 숫자가 무엇을 합산한 값인지 먼저 확인하는 습관이 여기서 생겼다.

즉시 장애가 아니라는 점도 함정이었다. 스왑 의존에서 성능 저하, 그다음 OOM Kill까지 천천히 진행되기 때문에 급해 보이지 않는다. 그래서 임계치 알람을 걸어 추세를 보게 만들었다.

JVM이 붙은 환경에서 OS 지표와 JVM 지표가 어긋나는 이유는 ECS 강제 재배포 후 메모리 사용률 급증에서 더 자세히 다뤘다.


이어 읽기