We will find a way, we always have.

-interstellar

Programming Language/자바

[자바] JVM 남이 주는거 아무거나 받아먹지 말자

Redddy 2024. 9. 29. 16:59

서론

문제 상황은 이렇다. 

이 글을 쓰기 위해 JDK 8을 설치하고 열심히 디버깅하면서 글에 첨부할 자료들을 캡쳐했다. 그리고 인텔리제이를 종료하고 시간지나 다시 켜니 라이센스 재인증 하라는 알림창이 떴다. 

 

재인증을 하려니 Problem with connection: SSL error probably caused by disabled SNI 와 Received fatal alert: handshake_failure 에러가 발생하였다.  

인텔리제이에서 연결을 요청하는데 proxy 문제인지 뭐 암튼 인터넷 연결이 되지 않아 라이센스를 인증하라는데 인증할 수가 없는 그런 상황이었다. 

 

사실 이런 문제 발생 예고는 이전부터 있었다. 언제부터인가 인텔리제이에서 db 커넥션 오류가 계속 발생하고 플러그인을 설치하려 marketplace에 들어가도 연결이 안된다며 접속이 안됐었다. 그때도 문제 해결을 위해 계속 찾아봤었는데, 마땅한 해결책이 나오지 않아서 그냥 넘어갔었다. 

 

하지만 이젠 단순히 marketplace에 들어가지 못하는게 아니라 라이센스 인증하라는 창이 떠서 코드를 편집할 수조차 없었다. 이제는 이 문제를 해결해야 할 때였다.

 

열심히 구글링도 해보고 인텔리제이 삭제했다 재설치를 반복해도 문제는 해결되지 않았다. 그러다 이 글을 발견해 나의 JVM 옵션 중 -Djsse.enableSNIExtension=false 이 녀석이 문제라는 것을 알았다. 

 

 

본론

인텔리제이에서 JVM 옵션을 변경하려면 Help -> Edit Custom VM Options을 클릭하면 설정할 수 있는 파일이 나온다. 

 

 

 

하지만 나 같은 경우 인텔리제이 들어가는 것도 아예 불가능했어서 인텔리제이 커뮤니티 용 설치해서 변경해주었다. 이렇게 짜치는 방법으로 변경하지 않고 파일 경로에 직접 접근해서 변경하는 것도 가능하다. 

 

C:\Users\{User_name}\AppData\Roaming\JetBrains\{인텔리제이 버전}\idea64.exe.vmoptions

 

 

현재 내가 사용하고 있는 VM Options들은 아래와 같다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-server
-Xms4096m
-Xmx4096m
-XX:NewRatio=3
-Xss16m
-XX:+AlwaysPreTouch
-XX:+TieredCompilation
-XX:ReservedCodeCacheSize=520m
-XX:SoftRefLRUPolicyMSPerMB=50
-XX:+UseCodeCacheFlushing
-Dsun.io.useCanonCaches=false
-ea
-Djava.net.preferIPv4Stack=true
-Dfile.encoding=UTF-8
-Dconsole.encoding=UTF-8
-XX:+UseG1GC
-XX:ErrorFile=$USER_HOME/java_error_in_idea_%p.log
-XX:HeapDumpPath=$USER_HOME/java_error_in_idea.hprof
 
cs

 

 

 

채찍비티 돌려서 확인한 결과,,,

 

  • -server: 서버 모드에서 JVM을 실행합니다. 서버 환경에서 성능을 최적화하기 위해 사용됩니다.
  • -Xms4096m: JVM의 힙 메모리 초기 크기를 4096MB(4GB)로 설정합니다. 애플리케이션 시작 시 할당되는 메모리입니다.
  • -Xmx4096m: JVM의 힙 메모리 최대 크기를 4096MB(4GB)로 설정합니다. 이 값을 초과하면 OutOfMemoryError가 발생할 수 있습니다.
  • -XX:NewRatio=3: 힙 메모리에서 Young generation(새롭게 생성된 객체를 위한 공간)과 Old generation(오래된 객체를 위한 공간)의 비율을 1:3으로 설정합니다. 즉, Old generation이 Young generation보다 3배 크다는 의미입니다.
  • -Xss16m: 각 스레드의 스택 크기를 16MB로 설정합니다.
  • -XX:+AlwaysPreTouch: JVM이 힙 메모리를 시작 시점에 미리 모두 할당합니다. 이것은 메모리 페이지를 미리 설정하여 페이지 폴트를 방지하고, 애플리케이션이 시작될 때 일관된 메모리 접근 시간을 보장합니다.
  • -XX:+TieredCompilation: 단계별 컴파일을 활성화합니다. JVM이 코드의 실행 빈도에 따라 적절한 컴파일 레벨을 적용하여 성능을 최적화합니다.
  • -XX:ReservedCodeCacheSize=520m: JIT 컴파일된 코드를 저장하는 메모리 크기를 520MB로 설정합니다.
  • -XX:SoftRefLRUPolicyMSPerMB=50: 소프트 레퍼런스가 LRU(최소 최근 사용) 방식으로 얼마나 오랫동안 유지되는지를 제어합니다. 이 설정은 MB당 50밀리초 동안 소프트 레퍼런스가 유지됨을 의미합니다.
  • -XX:+UseCodeCacheFlushing: 코드 캐시가 가득 찼을 때 코드를 플러시(삭제)하도록 설정합니다. 캐시 오버플로를 방지하고 성능 문제를 줄입니다.
  • -Dsun.io.useCanonCaches=false: 파일 경로 캐싱을 비활성화합니다. 일부 파일 시스템에서 성능 문제를 해결하는 데 사용될 수 있습니다.
  • -ea: 애설트(Assertion)를 활성화합니다. 디버깅 목적으로 코드에서 assert 문을 사용할 수 있게 합니다.
  • -Djava.net.preferIPv4Stack=true: JVM이 IPv4 스택을 우선 사용하도록 설정합니다. IPv6을 비활성화하고 IPv4로 네트워크 통신을 합니다.
  • -Dfile.encoding=UTF-8: 기본 파일 인코딩을 UTF-8로 설정합니다. 애플리케이션이 텍스트 파일을 읽고 쓸 때 이 인코딩을 사용합니다.
  • -XX:+UseG1GC: G1(Garbage First) 가비지 컬렉터를 사용합니다. 큰 힙에서 성능을 유지하면서 GC pause를 최소화하기 위해 설계된 가비지 컬렉터입니다.
  • -XX:ErrorFile=$USER_HOME/java_error_in_idea_%p.log: JVM에서 오류가 발생하면 해당 로그를 $USER_HOME/java_error_in_idea_%p.log에 기록합니다. %p는 프로세스 ID로 대체됩니다.
  • -XX:HeapDumpPath=$USER_HOME/java_error_in_idea.hprof: JVM에서 OutOfMemoryError가 발생하면 힙 덤프를 $USER_HOME/java_error_in_idea.hprof 파일에 기록합니다.

 


 

그리고 문제가 됐던 -Djsse.enableSNIExtension=false 이 녀석은 Java Secure Socket Extension (JSSE)에서 SNI(Server Name Indication) 확장을 비활성화하는 설정이다. 

SNI란?

SNI(Server Name Indication)는 TLS/SSL 프로토콜의 확장 기능 중 하나로, 하나의 IP 주소에서 여러 도메인을 호스팅할 수 있도록 한다. 클라이언트가 서버에 연결할 때, 요청하는 도메인의 이름을 서버에게 알려줘서 서버가 올바른 인증서를 선택할 수 있게 한다.

 

 

결론

이전에 내가 설정해놓은 옵션들은 어디 구글링하다가 누가 이렇게 세팅하면 좋다고 해서 해두었던 설정값들이었다. 이제 남이 주는거 함부러 받아 먹지 말아야겠다.

 

 

참고 혹은 읽어볼 글

https://techblog.woowahan.com/2628/

 

https://gist.github.com/mahmoudimus/ce9278d27267e109dda7292cfa1ba253

 

밸덩 JVM Parameter

 

오라클 문서 JVM Options