Java 코드의 컴파일 과정
- 개발자가 .java 파일을 생성하고, build 한다.
- .java 파일이 javac(java compiler)를 이용해 컴파일 된다.
- 컴파일 되면, .class 파일이 생성된다. (byte code라고 부른다.)
- Class Loader를 통해 JVM 메모리 내에 바이트 코드가 로드된다.
- JVM에 의해 OS에 맞는 기계어로 번역(interpretation)되고, 실행된다.
- 따라서 Java code는 시스템 아키텍쳐에 의존하지 않고, 코드 작성이 가능하다는 특성을 갖는 것이다.
여기서 컴파일과 빌드에 대한 용어를 다음과 같이 명확하게 정리하자.
- 빌드 (build)
- 개발자가 작성한 소스 코드를 실행 가능한 파일로 변환하는 과정을 의미한다.
- 컴파일 (compile)
- 컴파일러를 이용해 소스 코드를 기계가 해석 가능한 기계어로 변환해 목적 파일(object file)을 생성하는 행위를 의미한다.
자바의 메모리 영역
자바 프로그램이 실행되는 시점에서 JVM에 할당되는 메모리 공간은 다음과 같이 구성된다.
- Method 영역
- 전역 변수와 static 변수, 메서드를 저장한다.
- 프로그램의 시작 ~ 종료 시점까지 메모리에 남아있는다.
- Stack 영역
- 지역 변수와 매개 변수 데이터 값이 저장되는 메모리 공간이다.
- method를 호출하는 경우 할당되고, 종료시 해제된다.
- 이름에서 알 수 있듯이, stack (LIFO) 구조를 갖고, 변수에 새로운 데이터가 할당되면 이전 데이터는 지워진다고 한다.
- Heap 영역
- new 키워드로 생성되는 객체(인스턴스), 배열 등이 Heap 영역에 저장된다. GC(Garbage Collector)에 의해 관리되는 메모리 공간이 이 곳이다.
Method 영역은 JVM이 동작해서 크랠스가 로딩될 때 할당되며, Stack 영역은 컴파일 시점, Heap 영역은 런타임 도중에 할당된다.
Garbage Collection은 JVM 위에서 동작하는 기능으로, 자바 애플리케이션에서 더 이상 사용하지 않는 메모리 공간을 자동으로 수거하는 역할을 담당한다.
Garbage Collection, 줄여서 GC 작업을 수행하기 위해서 JVM이 애플리케이션의 실행을 모두 멈추고, GC를 실행하는 쓰레드를 제외한 모든 쓰레드를 멈추고(Stop the world라고 한다) 사용하지 않는 메모리 공간을 해제(Mark and Sweep 과정이라고 한다)한 뒤 작업을 재개한다.
이전에 리터럴에 대해 정리한 부분이 있는데, String type의 경우 Java 7버전 이후부터는 out of memory 같은 오류를 피하기 위해 JVM의 Heap 공간에 String constant pool에 String literal을 저장하고, 객체와 같이 관리되는 방식으로 변경되었다고 한다.
StringBuilder, StringBuffer 모두 String type과 달리 가변적인 데이터를 저장할 수 있다는 공통점을 지녔지만, Buffer의 경우 동기화 문제를 조작 가능하고 Builder는 그렇지 못하다는 차이점이 있어 멀티 쓰레드 환경에서는 StringBuffer를 싱글 쓰레드 환경에서는 StringBuilder를 사용하는 것이 좋다고 한다. (더 깊은 이해는 더 공부해야 알 수 있을 것 같다.)
GC의 대상은 Heap 메모리 영역에 한정되기 때문에, 다른 리터럴들은 관리의 대상이 아님을 유의하자. (다른 primitive type literal들은 method 영역에 저장된다.)
프록시에 대해서
프록시에는 두 가지의 종류가 존재한다.
- 포워드 프록시
- 클라이언트 앞에 위치
- 클라이언트가 proxy 서버와 통신한다.
- original 서버에 요청을 보내기 전에 캐싱한 정보 유무를 판단해서, 대신 제공할 수 있는 데이터를 프록시 서버가 제공
- 리버스 프록시
- WAS(Web Application Server) or WS(Web Server) 앞에 위치
- proxy 서버가 original 서버 (내부 망에 있는 서버)와 통신한다.
- 클라이언트로부터 전달된 데이터를 캐싱하는 등 유사하게 동작하나, 내부 망에 위치한 WAS or WS를 보호하는데 주 목적을 둔다.
원래 리버스 프록시라고 하는 개념을 몰랐는데, 프록시에 두 가지 개념이 존재한다는 것을 알 수 있었고, 리버스 프록시가 포워드 프록시와 담당하는 역할의 차이를 공부할 수 있었다.
요약하자면, 포워드 프록시는 기존에 알고있던 프록시 서버의 역할이고, 리버스 프록시는 내부 망에 있는 원 서버를 보호하기 위한 프록시 역할을 하는 프록시 서버를 의미한다고 이해할 수 있을 것 같다.
'TIL(Today I Learned)' 카테고리의 다른 글
Spring-Boot multi-module setting (0) | 2023.05.23 |
---|---|
Builder Pattern (빌더 패턴) (0) | 2023.05.18 |
JWT를 이용한 인증, 인가 구현 과정 기록 (0) | 2023.03.02 |
Spring Security를 이용한 비밀번호 암호화 로직 구현 과정 기록 (0) | 2023.02.28 |
사이드 프로젝트 JWT 적용 과정 기록 (0) | 2023.02.26 |
댓글