반응형

최근 기술 면접에서 질문 받은 키워드 중에 하나인 maven , gradle에 대해 알아보겠습니다.

 

Java/Spring 기반 프로젝트에서 Maven과 Gradle은 가장 널리 쓰이는 빌드 도구입니다.

둘 다 의존성 관리와 빌드 자동화를 담당하는데, 프로젝트 규모에 따라 체감 차이가 확실히 납니다.

 

1️⃣ Maven과 Gradle의 기본 개념

Maven

XML 기반 설정 (pom.xml)으로, 정해진 라이프사이클 중심(compile → test → package)으로 동작합니다.

Convention over Configuration — 정해진 구조를 따르면 추가 설정 없이 바로 빌드가 가능합니다.

Maven 프로젝트 생성하면 이런 구조로 만들어집니다.

프로젝트 폴더
 ├─ src
 │   ├─ main
 │   │   ├─ java        → 실제 프로그램 코드
 │   │   └─ resources   → 설정 파일 (예: application.yml)
 │   └─ test
 │       ├─ java        → 테스트 코드
 │       └─ resources
 └─ pom.xml             → 프로젝트 설명서

장점

  • 구조가 명확하고 예측 가능
  • 학습 난이도가 낮음
  • 레거시 및 엔터프라이즈 환경에서 안정적

단점

  • 설정이 길어지고 가독성이 떨어질 수 있음
  • 증분 빌드, 캐시 활용이 제한적

Gradle

Groovy / Kotlin DSL 기반으로, Task 중심 빌드 모델입니다. 유연한 확장성과 커스터마이징이 가능합니다.

장점

  • 증분 빌드, 빌드 캐시, 병렬 빌드 지원
  • 멀티 모듈, MSA 환경에서 빌드 성능 우수
  • CI/CD 친화적

단점

  • 러닝커브가 존재
  • 과도한 빌드 로직은 가독성 저하 가능

 

2️⃣ 성능 차이의 핵심: 증분 빌드란?

증분 빌드(Incremental Build) — 변경된 파일과 그 영향을 받는 부분만 다시 빌드하는 방식입니다.

Maven Gradle
기본적으로 전체 라이프사이클 실행 변경된 Task만 실행 (UP-TO-DATE 판단)


💡 코드 한 줄 수정 후 빌드할 때 체감 성능 차이가 가장 큽니다.

 

🔍 잠깐, Maven도 증분 빌드 되는 거 아니야?

Maven도 증분 빌드를 지원합니다. 하지만 동작 방식에 큰 차이가 있습니다.

구분 Maven Gradle
판단 기준 파일 수정 시간 (timestamp) 입력/출력 내용 해시값
정확도 낮음 (touch만 해도 재빌드) 높음 (실제 내용 변경만 감지)
캐시 공유 로컬 .m2 저장소만 로컬 + 원격 빌드 캐시 공유 가능
Task 단위 스킵 제한적 (플러그인 의존) 기본 지원 (UP-TO-DATE)
설정 플러그인별 개별 설정 필요 기본 활성화

 

Maven 증분 빌드의 한계

  • maven-compiler-plugin이 .java → .class 타임스탬프 비교
  • 파일 내용이 같아도 touch 하면 재컴파일됨
  • 테스트, 패키징 등 다른 단계는 증분 지원 미흡

Gradle의 차별점

  • 모든 Task가 입력/출력 정의 → 내용 기반 변경 감지
  • FROM-CACHE로 이전 빌드 결과 재사용
  • CI 서버 간 캐시 공유로 팀 전체 빌드 시간 단축

💡 결론: 둘 다 증분 빌드를 지원하지만, Gradle이 더 정밀하고 광범위하게 동작합니다.

 

3️⃣ 러닝커브란?

러닝커브(Learning Curve) — 새로운 기술이나 도구를 얼마나 빠르게 학습하고 생산성을 낼 수 있는지를 의미합니다.

Maven Gradle
낮음 상대적으로 높음
정해진 규칙 위주 Task 개념, DSL, 캐시 구조 이해 필요
"왜 이렇게 동작하는지" 몰라도 사용 가능 한 번 익히면 대규모 프로젝트에서 생산성 상승


💡 단기 생산성은 Maven, 장기 생산성은 Gradle입니다. 

 

4️⃣ Gradle이 빠르다고 느껴지는 이유

4-1. 증분 빌드

  • 입력/출력 기반 Task 판단
  • 변경 없는 Task는 스킵

4-2. 빌드 캐시 (Build Cache)

  • 동일한 입력 → 동일한 출력이면 재빌드 생략
  • 로컬 캐시 + CI 캐시 공유 가능

4-3. 병렬 빌드

  • 여러 작업을 동시에 처리해서 빌드 시간 단축
org.gradle.parallel=true

💡 멀티 모듈 프로젝트에서 효과가 극대화됩니다.


5️⃣ Gradle DSL 비교: Groovy vs Kotlin

Gradle은 빌드 스크립트를 코드로 작성합니다. 이때 선택하는 DSL이 성격을 크게 좌우합니다.

5-1. Groovy DSL

plugins {
    id 'org.springframework.boot' version '3.2.1'
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
}

특징

  • 간결한 문법
  • 기존 Gradle 예제 대부분이 Groovy
  • 동적 타이핑 → 런타임 에러 가능

5-2. Kotlin DSL

plugins {
    id("org.springframework.boot") version "3.2.1"
}

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-web")
}

특징

  • 타입 안정성
  • IDE 자동완성 우수
  • 빌드 스크립트도 컴파일 대상

5-3. Kotlin DSL은 느리다?

자주 나오는 오해가 있습니다.

"Kotlin DSL은 빌드 성능이 느리다"

 

  • 초기 설정(Configuration) 단계는 약간 느릴 수 있음
  • 하지만 실제 빌드 시간, 증분 빌드, CI 환경에서는 체감 차이 거의 없음

💡 성능보다 유지보수성과 안정성을 위한 선택입니다. 

 

6️⃣ Maven ↔ Gradle 전환 이유

Maven → Gradle 전환 시점

  • 멀티 모듈 프로젝트
  • CI 빌드 시간 병목
  • 마이크로서비스 아키텍처
  • 빈번한 배포
💡 성능 + 확장성 중심

Gradle → Maven (혹은 유지)

  • 단일 모듈, 단순 구조
  • 레거시 시스템
  • 팀 내 Gradle 숙련도 부족
💡 안정성 + 표준화 중심

 

7️⃣ 로컬에서 직접 성능 비교해보기 (실습)

Java + Gradle-Groovy / Gradle-Kotlin / Maven 총 3개 프로젝트를 생성해서 테스트해봤습니다.

7-1. 변경 없이 빌드

time mvn package   # Maven
time ./gradlew build   # Gradle
Maven Gradle
Total time: 0.445s BUILD SUCCESSFUL in 373ms
1 actionable task: 1 up-to-date


7-2. 코드 일부 수정 후 빌드

time mvn package   # Maven
time ./gradlew build   # Gradle
Maven Gradle
Total time: 0.686s BUILD SUCCESSFUL in 426ms
2 actionable tasks: 2 executed


포인트

  • Maven은 코드 변경 전/후 up-to-date 없이 실행됨
  • Gradle은 코드 변경 전에는 실행 대상 task = 1개인데 실제 실행은 생략됨 (up-to-date)
  • 코드 변경 후에는 영향을 받는 task 수가 증가하고, 실행 대상 task 2개 다 실행됨

7-3. 증분 빌드 효과 확인

./gradlew build

코드 수정 후 첫 빌드


→ 5개 task가 모두 영향을 받아 실행됨 (15초 소요)

변경 없이 다시 빌드



→ 5개 task 모두 up-to-date 판정 → 작업 수행 생략 (999ms)

💡 이것이 증분 빌드의 핵심입니다. 변경이 없으면 Gradle이 "이미 최신 상태"라고 판단해서 task를 스킵합니다. 15초 → 999ms, 약 15배 성능 향상을 확인할 수 있습니다. 

 

8️⃣ 어떤 시스템에 무엇이 적합할까?

환경 Maven Gradle
단일 서비스  
레거시 SI  
멀티 모듈  
MSA  
CI/CD 중심  
빠른 온보딩  

 

📌 마무리

  • 빌드 성능의 핵심Gradle의 구조
  • DSL 차이는 성능보다 유지보수성
  • 러닝커브는 존재하지만, 규모가 커질수록 Gradle의 이점이 커집니다
반응형
반응형

 

1. 기업문화적합도 검사 (약 40분, 최대 70분) , 340문항

   응답Ⅰ: A~D 문항 각각에 대하여 동의하는 정도에 따라 전혀 그렇지 않다 ~ 매우그렇다 중 하나를 선택 
    >> 총 4개 항목에 대해 선택
    응답Ⅱ: A~D 문항 중 상대적으로 네 개 문항 중 본인과 가장 가까운 것 한 개와 가장 먼 것 한 개를 골라 선택 
    >> 총 2개 항목에 대해 선택
 

> 약 30분 정도 소요됬습니다.

 

정도에 대해 체크하는건 안 헷갈렸는데, 제일 가까운 것 / 먼 것 고르는거에서는 은근 헷갈려서 처음에 좀 당황했어요.

정도 선택, 먼것 선택이 같은 라인에 있어서 체크 안하면 안넘어감 + 시간제한이 있어서 파다닥 해야합니다.

질문 전혀 그렇지 않다 그렇지 않다 보통이다 그렇다 매우 그렇다 가깝다 멀다

 

대충 이런식입니다!

정도는 5개 중에 하나 선택하고, 가깝다 멀다는 한 페이지당(4문항) 가까운 것 하나, 먼 것 하나 선택하면 됩니듀.

그럼 한 페이지에 대략 6개의 라디오버튼이 선택되어 있으면 됨.

 

2. 직무테스트 = 코딩테스트 (160분)

*개인 IDE 활용 가능

 

저는 Codility로 연습하긴했는데, 아직 익숙치 않아서 처음에 코딜리티로만 하다가 나중엔 그냥 IntelliJ로 문제 풀었습니다.

 

총 2시간 40분이 주어지는데, 총 3개의 문제 중에 1솔하고 나머지 2개는 못 풀었어요

그래서 2시간쯤 까지 풀다가, 40분 남기고 그냥 껐습니다. 다른 코테와 제일 다른거는 영어로 문제가 출제된다는 점.

 

1. 시뮬레이션, 자료구조 사용

> 비슷한 문제 : https://www.acmicpc.net/problem/33753

 

2. 클래스 메서드 구현

> 언어 선택이 따로 안되고, 지정된 언어로 구현해야해서 진짜 큰 당황. 그래도 풀어볼 수 있겠거니 했는데 메시지 출력하는거부터 모르겠어서 2번 문제 풀때 포기해야겠다 생각 강하게듬

 

3. 탐색, 그래프

> 비슷한 문제 : https://leetcode.com/problems/course-schedule/description/

뭔가 BFS DFS 로 풀었으면 풀렸을까? 싶기도 한데, 결국은 못 풀었다.

다음에 또 코테를 치게 된다면, BFS DFS에 대해서 확실하게 학습한다면 1솔 정도는 플러스 되지 않을까 싶다.

 

**다른 후기도 들어보니까, 3솔 했는데 생각지 못한? 테스트케이스에 걸려서 합격 하지 못했단 썰도 있더라구요

그래서 저도 1솔하긴했지만, 완벽한 1솔이라는 보장이 없어서 그냥 후기나 끄적여봅니다.

 

 

 

반응형

'recruit' 카테고리의 다른 글

[2024 하반기] GSAT 후기  (0) 2024.10.28
[2024 하반기] LTAB : 롯데인적성 후기  (6) 2024.10.27
반응형

 

 

서버에서 apachectl -k start 또는 httpd 명령으로 Apache를 실행했을 때 아래와 같은 오류가 나오는 경우가 있습니다.

 

 

AH00072: make_sock: could not bind to address 0.0..0:80
(13)Permission denied: AH00072: make_sock: could not bind to address

 

 

이 에러는 Apache가 80번 포트를 열 수 없을 때 발생합니다.

대표적인 원인은 다음과 같습니다 👇

 

 

1️⃣ root 권한이 없어 포트 바인딩 불가

 

리눅스에서는 1024 이하 포트(80, 443 등)를 열려면 root 권한이 필요합니다.

 

✅ 해결 방법

sudo apachectl -k start

 

혹은 root 권한 없이 실행하고 싶다면 아래처럼 실행 파일에 권한을 부여할 수 있습니다.

 

sudo setcap 'cap_net_bind_service=+ep' $(which httpd)

 

💡 which httpd 명령으로 실행 파일 경로를 확인한 후 적용하세요.

 

 

2️⃣ 이미 80번 포트를 다른 프로세스가 사용 중

 

nginx, 기존 Apache 프로세스, 또는 개발용 서버가 80 포트를 점유하고 있을 수 있습니다.

 

✅ 포트 점유 확인

sudo netstat -tuln | grep :80

# 또는

sudo lsof -i :80

 

 

✅ 해결

 1. 점유 중인 프로세스를 종료하거나

 2. Apache 설정 파일(httpd.conf)의 포트를 변경합니다.

sudo vi /etc/httpd/conf/httpd.conf

 

Listen 8080

 

이후 재시작:

sudo apachectl -k restart

 

 



3️⃣ DocumentRoot 권한 부족

 

웹 루트 디렉터리에 Apache 실행 계정(apache, www-data 등)의 권한이 없을 경우 발생합니다.

 

 

✅ Apache 설정 파일 위치 확인

apachectl -V

 

 출력 예시 :

-D HTTPD_ROOT="/etc/httpd"
-D SERVER_CONFIG_FILE="conf/httpd.conf"
  • 설정 파일 전체 경로: $HTTPD_ROOT/$SERVER_CONFIG_FILE
  • 예: /etc/httpd/conf/httpd.conf

✅ 설정 파일에서 DocumentRoot 찾기


설정 파일을 열거나 grep으로 검색:

grep -R "DocumentRoot" /etc/httpd/



출력 예시:

/etc/httpd/conf/httpd.conf:DocumentRoot "/var/www/html"


이 경우 웹 루트 디렉토리는 /var/www/html

• 가상호스트 사용 시에는 /etc/httpd/conf.d/*.conf 또는 /etc/apache2/sites-enabled/*.conf도 확인

 

✅ 권한 수정

sudo chown -R apache:apache /var/www/html
sudo chmod -R 755 /var/www/html

 

 

 

📌 마무리

  • root 권한 없음 sudo apachectl -k start
  • 포트 충돌 netstat / lsof로 확인 후 종료 or Listen 8080
  • 디렉터리 권한 부족 chown / chmod

 

 

🚀 참고 명령어 요약

# Apache 상태 확인

sudo systemctl status httpd

 

# 포트 확인

sudo netstat -tuln | grep :80

 

반응형
반응형

 

Apache 설정을 다루기 전에, 먼저 환경을 확인해보자

 

Apache 설정 이슈를 다루기 전에 먼저 운영 중인 서버의 환경을 정확히 확인해보자.

> OS / Apache 버전 / 활성화된 모듈

 


 

0️⃣ 시작 전 환경 확인

 

✔ OS 버전 확인

# 배포판 이름과 버전
cat /etc/os-release

# 커널 정보
uname -a

# RedHat 계열 배포판 버전
cat /etc/redhat-release

 

✔ Apache 버전 확인

# Apache 버전
apache2 -v       # Debian/Ubuntu
httpd -v         # RHEL/CentOS

 

✔ Apache 활성 모듈 확인

apache2ctl -M    # Debian/Ubuntu
httpd -M         # RHEL/CentOS

 


 

1️⃣ Redirect 404 동작 방식과 적용 배경

 

Apache의 Redirectmod_alias가 제공하는 기능이다.

특정 URL 접근 시 리다이렉트 없이 지정한 상태코드를 반환할 수 있다.

 

 

✔ Redirect 404를 사용한 이유

실제 페이지 내용을 보지 못해도, 반환되는 상태코드(403/404)만으로

해당 URL의 존재 여부를 유추할 수 있기 때문이다.

 

  • 404 → 존재하지 않음
  • 403 → 존재하지만 권한 없음

→ 즉, 상태코드만으로도 URL 존재 유무를 추측 가능해짐

 

보안적으로 이런 “추측 가능성”을 차단하고 싶어 일부 URL에 대해 404를 강제로 반환하도록 설정했다.

 


 

✔ mod_alias 활성화 여부 확인

httpd -M | grep alias

 

  • alias_module (shared) 출력 → 활성화
  • 출력 없음 → 비활성

 


 

✔ Apache 설정 파일 확인 경로

# Debian/Ubuntu
apache2ctl -V | grep SERVER_CONFIG_FILE

# RHEL/CentOS
httpd -V | grep SERVER_CONFIG_FILE

 


 

✔ 대표 적용 예시

 

예시 1: favicon.ico

Redirect 404 /favicon.ico

이 설정을 적용하면 /favicon.ico 요청은 별도 파일 탐색 없이 즉시 404를 반환한다.

 

예시 2: 루트(/) 전체 404

Redirect 404 /
  • 이 설정은 메인 페이지로 이동시키는 것이 절대 아님
  • “루트 경로 요청 → 무조건 404 반환”이라는 의미
  • Redirect 404는 리다이렉트가 아닌 즉시 상태코드 반환

 


 

2️⃣ /server-status 완전 차단

 

Apache 기본 설정(mod_status 활성화 시)에서는 /server-status

서버 상태 페이지로 연결된다.

 

운영 환경에서는 절대 노출되면 안 되는 페이지이기 때문에 완전 차단한다.

 

 

✔ 기존 핸들러 제거 (필수)

# <Location /server-status>
#     SetHandler server-status
#     Order deny,allow
#     Deny from all
#     Allow from 127.0.0.1
# </Location>

 

✔ 404로 완전 차단

Redirect 404 /server-status

 

  • 이제 /server-status 접근은 무조건 404
  • 별도 <Location> 블록 추가 필요 없음
  • 존재 여부 추측도 불가

 


 

3️⃣ Burp Suite로 400 Bad Request 테스트

 

잘못된 HTTP 요청을 Apache에 직접 전달해

서버가 정상적으로 400 Bad Request를 반환하는지 확인할 수 있다.

 

 

✔ Burp Proxy 활성화

 

  • Burp Suite → ProxyIntercept On
  • Burp의 내장 브라우저(Open Browser) 사용 또는 Chrome 프록시 설정

 

 

✔ 브라우저에서 테스트 URL 요청

예:

http://localhost/js/#test

브라우저는 fragment(#)를 서버로 보내지 않지만,

Burp는 요청을 수정할 수 있다.

 

 

✔ Burp에서 요청 가로채기 → 잘못된 요청으로 수정

정상 요청:

GET /js/ HTTP/1.1

수정 후 (RFC 위반 → 무조건 400 유발):

GET /js/# HTTP/1.1

또는:

GET /js/### HTTP/1.1

Forward로 서버에 전달하면

→ Apache는 100% 400 Bad Request로 응답한다.

 


 

4️⃣ 기본 에러 페이지 노출 방지 (커스텀 에러 페이지)

 

Apache는 기본적으로 매우 단순한 HTML 에러 페이지를 보여준다.

이는 다음 문제를 유발한다.

 

  • 서버 정보 노출
  • URL 존재 여부 추정 가능
  • 사용자 경험 저하

 

따라서 커스텀 에러 페이지 적용을 권장한다.

 

 

✔ 설정 예시

ErrorDocument 404 /errors/404.html
ErrorDocument 403 /errors/403.html
ErrorDocument 400 /errors/400.html

 

✅ 위와 같이 로컬 html 파일로 연결되지 않을 경우에는 url 리다이렉션을 통해 해결이 가능하다.

 

ErrorDocument 404 https://example.com/error

 

✔ Reload

apachectl stop
apachectl start

이제 모든 에러(400/403/404)는 사용자 정의 페이지로 출력된다.

 

 


 

📌 마무리

 

이번 정리에서는 실제 운영 환경에서 자주 발생하는 Apache 이슈들을 다뤘다.

 

  • Redirect 404를 통한 존재 여부 추측 차단
  • /server-status, /favicon.ico 같은 기본 엔드포인트 완전 차단
  • BurpSuite를 이용한 400 응답 테스트
  • 기본 에러 페이지 → 커스텀 페이지로 통일
반응형
반응형

 

윈도우 초기화를 진행하다가,

복구 환경을 찾을 수 없음” 오류가 발생했다.

 

 


 

📌 1. “복구 환경을 찾을 수 없음” 오류 원인

 

Windows 초기화 시 아래와 같은 메시지가 나오면:

 

“복구 환경을 찾을 수 없습니다.”

 

이는 대부분 WinRE(Windows Recovery Environment) 손상 또는 비활성화 때문에 발생한다.

 

대표 원인:

 

  • Recovery 파티션 손상
  • winre.wim 파일 삭제/누락
  • WinRE 경로 설정 사라짐
  • 초기화 과정 중 파일 손상
  • 관리자 권한 없이 활성화 시도

 

reagentc /info 명령어로 확인해보면

Windows RE가 Disabled로 표시된다고 하는데, 나는 Enabled로 표시됬다.

 

reagentc /enable

 

명령어를 통해 활성화 시켜주고 나니, Windwos 초기화를 실행할 수 있었다.

 


 

📌 2. 초기화 중 계정 생성 화면에서 넘어가지 않는 문제

 

초기화 후 OOBE(초기 설정) 화면에서

“다음”이 눌리지 않거나 계정 생성이 안 되는 현상이 있다.

 

 

주요 원인

  • MS 계정 강제 로그인
  • 네트워크 문제
  • OOBE 버그
  • 로컬 계정 비활성화

 

 

✔  해결 방법  : BYPASSNRO

 

MS 계정 강제 우회하여 로컬 계정 생성 화면을 강제 활성화하는 방법.

 

 

➤ 실행 방법

  1. 계정 생성 화면에서
  2. Shift + F10 (→ CMD 열림)
  3. 입력:
OOBE\BYPASSNRO

 

 

   4. 엔터 → 자동 재부팅

   5. MS 계정 생성 / 로그인 없이 바탕화면 접속 확인

 

 

 

반응형
반응형

작년에 이어 올해도 또 정보기..
 
수수료는 18,800원으로 작년과 동일합니다!
 
그럼 시험 준비는 어떻게 했냐?
작년에 산 '알기사 정보보안기사 필기 2024'로 공부!
 

 
✏️ 공부 루틴
: 요약집 PART별로 정독 -> 해당 PART 핵심기출 1200제 풀기 -> 오답노트 + 틀린 문제 이론 찾아보기
 
이렇게 PART 7개 다 보긴 했는데 결국 기출을 못 돌려서 망한 듯..?
작년의 나 -> 올해의 나 "기출 3개년 풀면 필기는 합격 노려볼만하다며.."
작년의 나 <- 올해의 나 "올해 4회엔 그렇게 해볼게 ㅠㅠ"
 
*입실시간

나름(?) 넉넉히 1시간 전쯤 출발한 거 같은데
2부 1310분 넘어서 도착해서 나 못 들어가는 거 아냐?
했는데 시험시작하는 30분 전이면 들여보내주는 거 같다..!

**기억을 더듬어보면 20-25분 사이에 도착한 거 같은데 신분증 확인하고 바로 들여보내줌 ㅠㅠ 하 다행🥹

결과는? CBT라서 바로 보이더라고요^^

 
작년 정보기 결과)

 ㅎㅎ... 이제 남은 건 4회 딱 하나..

 

새로 알기사 책도 사고... 좀 열심히 공부해서 필기 합격 후기도 돌아오겠숩니당 👋🏻

반응형
반응형

 

* 면접 질문이었다고 공유 받은 키워드.

공유 받은 김에 나도 공부하고, 정리할겸 끄적여본당 *

 

💡 Java GC 쉽게 이해하기 - Young & Old Generation 개념과 실습 예제

 

Java 개발을 하다 보면 꼭 한 번쯤은 GC(Garbage Collection) 를 마주하게 됩니다.

특히 성능 이슈가 발생했을 때 GC의 동작 방식과 로그를 이해하면 큰 도움이 되죠.

 

이번 포스팅에서는 Young Generation과 Old Generation의 개념을 정리하고,

간단한 Java 코드와 JVM 옵션을 통해 실제 GC 동작을 살펴보는 실습을 진행해보겠습니다.

 


 

📌 GC의 세대 구분이란?

 

JVM은 힙 메모리를 크게 Young GenerationOld Generation으로 나눠 관리합니다.

 

세대 설명 관련 GC
Young Generation 새로 생성된 객체가 저장되는 영역. 대부분의 객체는 이곳에서 생성되고 빠르게 소멸됨 Minor GC가 발생
Eden Young 영역의 일부분으로, 객체가 최초로 생성되는 곳 Minor GC 시 대부분 제거됨
Survivor Eden에서 살아남은 객체가 일시적으로 이동하는 공간 일정 횟수 생존 시 Old로 승격
Old (Tenured) Generation Young에서 오래 살아남은 객체가 이동하는 영역 ⚠️ Full GC 대상
Permanent / Metaspace 클래스 메타데이터 등을 저장 (Java 8 이후 Metaspace로 변경됨) 클래스 언로드 시 정리

 

👉 대부분의 객체는 Eden 영역에서 생성되고 Minor GC를 통해 제거됩니다.

👉 생존한 객체는 Survivor → Old Generation으로 이동하며, Full GC 대상이 됩니다.

 


 

🧪 GC 동작 확인을 위한 자바 예제

아래 코드는 Eden 영역을 가득 채워 GC를 유도하고,

일부 객체는 참조를 유지하여 Old Generation으로 이동하게 만드는 예제입니다.

package com.example.demo;

import java.util.ArrayList;
import java.util.List;

public class GCDemo {
    private static final int _1MB = 1024 * 1024;

    public static void main(String[] args) {
        List<byte[]> survivors = new ArrayList<>();

        System.out.println("▶ Eden 영역에 객체 생성 시작");

        for (int i = 0; i < 50; i++) {
            byte[] temp = new byte[_1MB]; // 1MB 크기의 객체 생성
            if (i % 5 == 0) {
                survivors.add(temp); // 일부 객체는 참조 유지 → Old로 이동 가능성
            }

            try {
                Thread.sleep(100); // GC 여유 시간 확보
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        System.out.println("▶ 객체 생성 완료");

        System.gc(); // 명시적 Full GC 유도

        try {
            Thread.sleep(3000); // GC 로그 출력 대기
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("▶ 프로그램 종료");
    }
}

 

 


 

⚙️ 실행 방법 및 JVM 옵션

 

✅ 1. 컴파일

javac -d . GCDemo.java

 

✅ 2. GC 로그 옵션을 추가하여 실행

java -Xms128m -Xmx128m \
     -XX:+UseSerialGC \
     -XX:+PrintGCDetails \
     -XX:+PrintGCDateStamps \
     -Xloggc:gc.log \
     -cp . \
     com.example.demo.GCDemo

 

🛠 JVM 옵션 설명

옵션설명

-Xms128m -Xmx128m 힙 메모리를 작게 설정하여 GC 유도
-XX:+UseSerialGC 단순한 GC 방식 (싱글 스레드)
-XX:+PrintGCDetails GC 동작의 상세 로그 출력
-XX:+PrintGCDateStamps GC 발생 시간 표시
-Xloggc:gc.log 로그를 파일로 저장

 

 


 

📁 GC 로그 예시

 

아래는 gc.log 파일의 일부 내용 예시입니다.

[3.377s][info][gc,start    ] GC(0) Pause Young (Allocation Failure)
[3.380s][info][gc,heap     ] GC(0) DefNew: 34865K(39296K)->4352K(39296K) Eden: 34865K(34944K)->0K(34944K) From: 0K(4352K)->4352K(4352K)
[3.380s][info][gc,heap     ] GC(0) Tenured: 0K(87424K)->3266K(87424K)

 

  1. Young GC 발생 – Eden 공간 부족으로 Minor GC가 트리거됨
  2. Eden → Survivor – Eden에 있던 대부분의 객체가 제거되었고, 일부는 Survivor 영역으로 생존
  3. Survivor → Old – 생존 객체 일부는 Old Generation으로 승격됨

 

반응형
반응형
 개발환경 

 

- Spring Boot 3.3.3

- Java 17

 

war 배포

 

1. ROOT.war 파일 생성

build.gradle에 하단 내용 추가하고 build 실행하면

프로젝트 폴더 > build > libs 밑에 war 파일이 하나 만들어진다.

plugins {
    id 'war'
}

tasks.named('bootWar') {
    enabled = false
}

 

만들어진 jar 파일명을 ROOT.war 로 변경해준다.

 

2. 외부 톰캣에 war 파일 배포

- Tomcat 설치 폴더 > webapps 폴더에 war 파일을 복사/이동해준다.

 

3. 톰캣 실행

- Tomcat 설치 폴더 > bin 이동

./startup.sh 로 실행시킨다.

 

4. 로그 확인

실행 후 Tomcat 설치 폴더 > logs 에서

tail -F catalina.out 으로 로그 확인하면 된다!

 

실행 결과

 

현재 8090 포트에서 실행되고 있는걸 확인할 수 있다 🐈‍⬛

반응형

+ Recent posts