2021년 10월 21일 TIL
엔티티의 생명주기
비영속(new/transient)
순수한 객체 상태이며, **영속성 컨텍스트와 관련이 없는 상태
영속(managed)
EntityManager를 통해 엔티티를 영속성 컨텍스트에 저장되어 영속성 컨텍스트가 관리하는 상태
준영속(detached)
영속성 컨텍스트에 저장되었다가 분리된(detached) 상태
삭제(removed)
엔티티를 영속성 컨텍스트와 데이터베이스에서 삭제한 상태
Git Flow vs Github Flow vs Gitlab Flow
- Git flow
- feature / develop / release / hotfix / master
- GitHub Flow
- master를 항상 배포하고, 그냥 마스터만 두고 쓰는 방식
- Gitlab Flow
- Master / Pre-Production / Production
JVM
참조 : https://1-7171771.tistory.com/125?category=865872

- 프로그램이 실행되면 JVM은 OS로 부터 이 프로그램이 필요로 하는 메모리를 할당받는다.
- 자바 컴파일러(javac)가 자바 코드(.java)를 읽어들여 자바 바이트코드(.class)로 변환한다.
- Class Loader를 통해 class 파일들을 JVM으로 로딩한다.
- 로딩된 class 파일들은 실행엔진(Execution engine)을 통해 해석된다.
- 해석된 바이트 코드는 Runtime Data Areas에 배치되어 실질적으로 수행한다.

클래스 로더 시스템 (Class Loader)
JVM으로 .class파일을 로드하고, 링크를 통해 배치하는 작업을 수행하는 모듈이다. 자바는 Runtime시에 동적으로 클래스를 로드(=로딩)한다. (클래스를 처음으로 참조할 때, 해당 클래스를 로드하고 링크한다는 것이다.)
쉽게말해서 자바 바이트코드를 읽어들여서 메모리에 적절하게 배치하는게 클래스 로더가 하는일이다.
클래스 로더는 크게 로딩,링크,초기화 세 가지로 나뉜다.
- 로딩 : 클래스를 읽어오는 과정
- 링크 : 객체를 연결하는 과정
- 초기화: static 값들 초기화 및 변수에 할당
실행 엔진(Execution Engine)
클래스를 실행시키는 역할을 한다. 클래스 로더가 바이트 코드를 메모리에 배치시키는 역할을 한다면 실행 엔진은 이것을 실행시킨다.
자바 컴파일러를 통해 변환된 바이트 코드는 기계가 바로 실행할 수 있는 언어가 아닌 인간이 이해하기 편한 언어에 가깝기 때문에 아래 두 가지 방식을 통해 기계가 이해할 수 있는 언어로 변환해준다.
(앞으로는 인간이 이해하기 편한 언어를 네이티브 코드로 표현하겠다.)
-
Interpreter(인터프리터)
실행 엔진은 자바 바이트 코드를 한줄씩 읽어서 기계가 이해할 수 있는 언어로 변환한다.
-> 한줄씩 수행하기 때문에 속도가 매우 느리다.
-
JIT(Just In Time)
인터프리터의 효율을 높이기 위해, 인터프리터가 반복되는 코드를 발견하면 JIT 컴파일러로 반복되는 코드를 모두 기계가 이해할 수 있는 언어인 네이티브 코드로 바꿔둔다. 그 다음부터 인터프리터는 네이티브코드로 컴파일된 코드를 바로 사용한다. 네이티브 코드는 캐시에 보관하기 때문에 한 번 컴파일된 코드는 빠르게 수행될 수 있다.
JIT 컴파일러가 컴파일 하는 과정은 바이트 코드를 인터프리팅하는 것보다 훨씬 오래걸리므로 한번만 실행하는 코드라면 인터프리팅 하는 것이 유리하다.
-> 이 과정은 JVM이 내부적으로 해당 메서드의 실행 빈도를 체크하여 판단한다.
-
GC(Garbage Collector)
더이상 참조되지 않는 객체를 모아서 정리한다.
JVM 메모리 영역
PC Register
Thread가 시작될 때 생성되며, 각 Thread별로 고유의 독립적인 공간을 가진다. Thread가 어떤 부분을 어떤 명령으로 실행해야 할 지에 대한 기록을 하는 부분으로 현재 수행중인 JVM명령의 주소를 갖는다.
Stack (스택 영역)
프로그램 실행 과정에서 임시로 할당되었다가 메소드 호출이 종료됨과 동시에 소멸되는 데이터를 저장하기 위한 영역이다.
메소드가 호출될 때 마다 메모리 안에 그 메서드만을 위한 공간인 스택 프레임이 생성되며, 그 안에는 메소드의 지역변수와 파라미터 변수가 포함되어 있다.
메서드의 수행이 끝나면 스택 프레임 별로 삭제된다.
Native method stack
.class 가 아닌 실제 실행할 수 있는 기계어로 작성된 프로그램을 실행시키는 영역으로, Java로 작성된 코드가 아닌 C 또는 C++로 작성된 코드들의 공간이다.
JNI(Java Native Interace)를 통해 바이트 코드로 전환하여 저장하게 된다. JNI는 아래 코드처럼 native 키워드가 붙은 메소드를 호출한다.
@HotSpotIntrinsicCandidate
public static native Thread currentThread();
모든 Thread가 공유하는 영역
Method Area(메소드 영역)
메소드 영역은 다른말로 클래스 영역 또는 스태틱 영역이라고도 불린다.
클래스 수준의 정보(클래스 이름, 부모 클래스 이름, 메소드, 변수등)가 저장된다.
클래스 정보를 처음 메모리 공간에 올릴 때 초기화 되는 대상을 저장하기 위한 메모리 공간이다. 대부분의 인스턴스 생성이 메소드 내에서 명령하고 호출하기 때문에 사실상 컴파일 된 바이트 코드의 대부분이 메소드 바이트코드이기 때문에 대부분의 바이트 코드가 모두 이 공간에 올라간다고 봐도 상관 없다.
이 공간에는 추가적으로 Runtime Constant Pool 이라는 별도의 영역이 존재하는데, 상수 자료형을 저장하여 참조하고 중복을 막아 효율적인 메모리를 관리하는 역할을 한다.
메소드 영역은 GC의 관리 대상이다.
heap(힙 영역)
객체를 저장하는 가상 메모리 공간으로, new키워드로 생성된 객체와 배열을 저장하며 메소드 영역에 올라온 클래스들만 객체로 생성 가능하다.
힙 영역은 다음과 같이 세 영역으로 나뉜다.
