๐ JAVA 01 - JAVA ๊ฐ์ฒด ์์ฑ ๊ณผ์ ๊ณผ JVM ๋ฉ๋ชจ๋ฆฌ ๊ตฌ์กฐ ์ฌํ
1์ฃผ์ฐจ 1์ผ์ฐจ - ๊ฐ์ฒด ์์ฑ ๊ณผ์ ๊ณผ JVM ๋ฉ๋ชจ๋ฆฌ ๊ตฌ์กฐ ์ฌํ
Java ๋ฐฑ์๋ ๋ฉด์ ์์ ๊ต์ฅํ ์์ฃผ ๋ฑ์ฅํ๋ ์ง๋ฌธ:
โnew ํค์๋๋ก ๊ฐ์ฒด ์์ฑ ์ ์ด๋ค ์ผ์ด ๋ฐ์ํ๋์?โ
๋ง์ ๊ฒฝ์ฐ:
- Heap์ ๊ฐ์ฒด ์์ฑ
- Stack์ ์ฐธ์กฐ ์ ์ฅ
์ ๋๋ก ๋๋๋ค.
ํ์ง๋ง ์ค์ ์ค๊ฒฌ ์ด์ ๋ฉด์ ์์๋:
- ํด๋์ค ๋ก๋ฉ
- ๋ฉ๋ชจ๋ฆฌ ํ ๋น
- ๊ฐ์ฒด ์ด๊ธฐํ
- ์ฐธ์กฐ ์ฐ๊ฒฐ
- GC Root
- ๊ฐ์ฒด ์๋ช ์ฃผ๊ธฐ
๊น์ง ์ฐ๊ฒฐํด์ ์ค๋ช ํ ์ ์์ด์ผ ํ๋ค.
ํนํ Spring ๊ธฐ๋ฐ ๋ฐฑ์๋์์๋:
๊ฐ์ฒด ์์ฑ ์์ฒด๊ฐ ์ฑ๋ฅ๊ณผ ์ง๊ฒฐ
๋๊ธฐ ๋๋ฌธ์ ๋งค์ฐ ์ค์ํ๋ค.
JVM ๋ฉ๋ชจ๋ฆฌ ๊ตฌ์กฐ
graph TD
JVM[JVM Memory]
JVM --> MA[Method Area]
JVM --> HEAP[Heap]
JVM --> STACK[Stack]
MA --> MA1[ํด๋์ค ์ ๋ณด]
MA --> MA2[static ๋ณ์]
MA --> MA3[๋ฐํ์ ์์ ํ]
HEAP --> H1[User ๊ฐ์ฒด]
HEAP --> H2[Order ๊ฐ์ฒด]
HEAP --> H3[String ๊ฐ์ฒด]
STACK --> S1[Thread-1 Stack]
STACK --> S2[Thread-2 Stack]
JVM ๋ฉ๋ชจ๋ฆฌ๋ ํฌ๊ฒ ๋ค์ ์์ญ์ผ๋ก ๋๋๋ค.
- Method Area
- Heap
- Stack
- PC Register
- Native Method Stack
์ค๋ ํต์ฌ์:
- Heap
- Stack
- Method Area
์ดํด๋ค.
Heap
Heap์:
๊ฐ์ฒด๊ฐ ์ ์ฅ๋๋ ๋ฉ๋ชจ๋ฆฌ ์์ญ
์ด๋ค.
์์:
1
User user = new User();
์ค์ User ๊ฐ์ฒด๋ Heap์ ์์ฑ๋๋ค.
์ Heap์ ๊ณต์ ์์ญ์ผ๊น?
graph LR
T1[Thread-1] --> H[Heap์ User ๊ฐ์ฒด]
T2[Thread-2] --> H
๋งค์ฐ ์ค์ํ ์ง๋ฌธ.
Heap์:
์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์ผ ๊ฐ์ฒด๋ฅผ ๊ณต์ ํ ์ ์๋๋ก ์ค๊ณ
๋์๋ค.
๋ง์ฝ ์ค๋ ๋๋ณ Heap์ ์ฌ์ฉํ๋ค๋ฉด:
- ๊ฐ์ฒด ๊ณต์ ์ด๋ ค์
- ๋ฉ๋ชจ๋ฆฌ ๋ญ๋น ์ฆ๊ฐ
- ๊ฐ์ฒด ์ ๋ฌ ๋น์ฉ ์ฆ๊ฐ
๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
์ฆ:
โ๊ฐ์ฒด ๊ณต์ ํจ์จโ
์ ์ํด Heap์ ๊ณต์ ๋ฉ๋ชจ๋ฆฌ๋ก ์ค๊ณ๋์๋ค.
Stack
Stack์:
๋ฉ์๋ ํธ์ถ๊ณผ ์ง์ญ ๋ณ์ ์ ์ฅ ์์ญ
์ด๋ค.
์์:
1
2
3
public void test() {
User user = new User();
}
์ฌ๊ธฐ์:
- user ๋ณ์ โ Stack
- ์ค์ User ๊ฐ์ฒด โ Heap
์ ์ฅ.
์ Stack์ ์ค๋ ๋๋ณ ๋ ๋ฆฝ์ผ๊น?
graph TD
T1[Thread-1 Stack]
T2[Thread-2 Stack]
T1 --> A1[methodA]
T1 --> A2[local variable]
T2 --> B1[methodB]
T2 --> B2[local variable]
์ด์ :
๋ฉ์๋ ์คํ ํ๋ฆ ์ถฉ๋ ๋ฐฉ์ง
๋๋ฌธ์ด๋ค.
๋ฉ์๋ ํธ์ถ ์ํ๋: ์ค๋ ๋๋ง๋ค ๋ ๋ฆฝ์ ์ด์ด์ผ ํ๋ค.
๋ฐ๋ผ์:
- ์ง์ญ ๋ณ์
- ๋งค๊ฐ๋ณ์
- ๋ฐํ ์ ๋ณด
๋ฑ์ ๋ ๋ฆฝ ๊ด๋ฆฌํ๋ค.
Method Area
ํด๋์ค ๋ฉํ๋ฐ์ดํฐ ์ ์ฅ ์์ญ.
์ ์ฅ ๋์:
- ํด๋์ค ์ ๋ณด
- static ๋ณ์
- ๋ฐํ์ ์์ ํ
- ๋ฉ์๋ ์ ๋ณด
static ๋ณ์๋ ์ ๋ณ๋ ๊ด๋ฆฌํ ๊น?
์์:
1
static int count = 0;
static์:
๊ฐ์ฒด๋ณ ๋ฐ์ดํฐ๊ฐ ์๋๋ผ ํด๋์ค ๊ณต์ฉ ๋ฐ์ดํฐ
์ด๋ค.
๋ฐ๋ผ์: Heap ๊ฐ์ฒด ๋ด๋ถ๊ฐ ์๋๋ผ ๋ณ๋ ๋ฉ๋ชจ๋ฆฌ ์์ญ์์ ๊ด๋ฆฌํ๋ค.
๊ฐ์ฒด ์์ฑ ๊ณผ์
graph TD
A[new User ์คํ] --> B[ClassLoader ํ์ธ]
B --> C[Heap ๋ฉ๋ชจ๋ฆฌ ํ ๋น]
C --> D[๊ธฐ๋ณธ๊ฐ ์ด๊ธฐํ]
D --> E[์์ฑ์ ํธ์ถ]
E --> F[Stack ์ฐธ์กฐ ์ ์ฅ]
F --> G[GC Root ์ฐ๊ฒฐ]
๋ค์ ์ฝ๋ ๊ธฐ์ค์ผ๋ก ๋ณด์.
1
User user = new User();
JVM ๋ด๋ถ์์๋ ๊ฝค ๋ง์ ๊ณผ์ ์ด ๋ฐ์ํ๋ค.
1. ํด๋์ค ๋ก๋ฉ ํ์ธ
JVM์ ๋จผ์ :
User ํด๋์ค๊ฐ ๋ฉ๋ชจ๋ฆฌ์ ์กด์ฌํ๋๊ฐ?
ํ์ธํ๋ค.
์์ผ๋ฉด:
- ClassLoader ๋์
- .class ๋ก๋ฉ
์ํ.
์ ๋ฐํ์ ๋ก๋ฉ ๊ตฌ์กฐ์ผ๊น?
Java๋:
Runtime Dynamic Loading
์ง์ ์ธ์ด๋ค.
์ฆ: ํ์ํ ์์ ์ ํด๋์ค ๋ก๋ฉ ๊ฐ๋ฅ.
์ฅ์ :
- ๋ฉ๋ชจ๋ฆฌ ํจ์จ
- ์ ์ฐ์ฑ
- ํ๋ ์์ํฌ ๊ตฌํ ์ฉ์ด
2. Heap ๋ฉ๋ชจ๋ฆฌ ํ ๋น
๊ฐ์ฒด ์ ์ฅ ๊ณต๊ฐ ์์ฑ.
์ด๋:
- ํ๋ ๊ธฐ๋ณธ๊ฐ ์ด๊ธฐํ
- ๋ฉ๋ชจ๋ฆฌ ํ๋ณด
์ํ.
์์:
1
2
3
int -> 0
boolean -> false
reference -> null
์ ๊ธฐ๋ณธ๊ฐ ์ด๊ธฐํ๋ฅผ ํ ๊น?
Java ํต์ฌ ์ฒ ํ:
โ์์ ์ฑโ
๋๋ฌธ์ด๋ค.
C/C++์ฒ๋ผ: ์ฐ๋ ๊ธฐ๊ฐ ๋ ธ์ถ ๋ฐฉ์ง ๋ชฉ์ .
3. ์์ฑ์ ํธ์ถ
์ดํ ์์ฑ์ ์คํ.
1
new User();
์์ฑ์ ๋ด๋ถ ๋ก์ง ์ํ.
4. ์ฐธ์กฐ ์ฐ๊ฒฐ
graph LR
S[Stack์ user ๋ณ์] --> H[Heap์ User ๊ฐ์ฒด]
์ต์ข ์ ์ผ๋ก:
1
User user
์ฐธ์กฐ ๋ณ์๊ฐ Stack์ ์์ฑ๋๊ณ : Heap ๊ฐ์ฒด ์ฃผ์ ์ฐธ์กฐ.
๊ตฌ์กฐ:
1
2
Stack
user -----> Heap(User ๊ฐ์ฒด)
GC Root์ ๊ฐ์ฒด ์๋ช ์ฃผ๊ธฐ
Reachable ๊ฐ์ฒด
graph TD
ROOT[GC Root]
ROOT --> USER[User ๊ฐ์ฒด]
USER --> ORDER[Order ๊ฐ์ฒด]
Unreachable ๊ฐ์ฒด
graph TD
ROOT[GC Root]
OBJ[User ๊ฐ์ฒด]
Java GC ํต์ฌ ๊ธฐ์ค:
Reachability(๋๋ฌ ๊ฐ๋ฅ์ฑ)
์ด๋ค.
GC Root๋?
๋ํ GC Root:
- Stack ์ง์ญ ๋ณ์
- static ๋ณ์
- JNI ์ฐธ์กฐ
์ Reachability ๊ธฐ์ค์ ์ฌ์ฉํ ๊น?
๋จ์ ์๊ฐ ๊ธฐ์ค ์ ๊ฑฐ๋ ์ํํ๋ค.
์์:
1
User user = cache.get();
์ค๋๋ ๊ฐ์ฒด๋ผ๋: ์ฌ์ ํ ์ฌ์ฉ ์ค์ผ ์ ์๋ค.
๋ฐ๋ผ์ JVM์:
โ์ฐธ์กฐ ๊ฐ๋ฅ ์ฌ๋ถโ
๋ก ํ๋จํ๋ค.
๊ฐ์ฒด๊ฐ GC ๋์์ด ๋๋ ๊ณผ์
์์:
1
2
3
public void test() {
User user = new User();
}
๋ฉ์๋ ์ข ๋ฃ ์:
- Stack Frame ์ ๊ฑฐ
- user ์ฐธ์กฐ ์ ๊ฑฐ
๋ฐ์.
์ดํ Heap ๊ฐ์ฒด๋:
GC Root๋ก๋ถํฐ ๋๋ฌ ๋ถ๊ฐ๋ฅ
์ํ๊ฐ ๋๋ค.
๊ทธ๋ GC ๋์ ๊ฐ๋ฅ.
์ ๊ฐ์ฒด ์์ฑ ๋น์ฉ์ด ์ค์ํ ๊น?
graph TD
A[๊ฐ์ฒด ์์ฑ ์ฆ๊ฐ] --> B[Heap ์ฌ์ฉ๋ ์ฆ๊ฐ]
B --> C[GC ๋น๋ ์ฆ๊ฐ]
C --> D[Stop-The-World ์ฆ๊ฐ]
D --> E[์๋ต ์ง์ฐ ๋ฐ์ ๊ฐ๋ฅ]
Java๋ ๊ฐ์ฒด ์์ฑ์ด ์ฌ์ด ์ธ์ด๋ค.
ํ์ง๋ง ๋๊ท๋ชจ ํธ๋ํฝ ํ๊ฒฝ์์๋:
- ๊ฐ์ฒด ์์ฑ ์ฆ๊ฐ
- Heap ์ฌ์ฉ ์ฆ๊ฐ
- GC ์ฆ๊ฐ
- STW ์ฆ๊ฐ
๋ก ์ด์ด์ง ์ ์๋ค.
์ค์ ์ฅ์ ์ฌ๋ก
๋ํ ์ฌ๋ก:
- API ์๋ต๋ง๋ค DTO ๊ณผ๋ค ์์ฑ
- ๋ฌธ์์ด ๋ฐ๋ณต ์์ฑ
- ๋ถํ์ํ ๊ฐ์ฒด ๋ณํ
๊ฒฐ๊ณผ:
- GC ๊ณผ๋ถํ
- ์๋ต ์ง์ฐ
- CPU ์ฆ๊ฐ
๋ฐ์ ๊ฐ๋ฅ.
์ค๋ฌดํ ๊ด์
Spring ์๋ฒ๋: ์์ฒญ๋ง๋ค ๋งค์ฐ ๋ง์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค.
์์:
- Request DTO
- Response DTO
- Entity
- ๋ก๊ทธ ๊ฐ์ฒด
๋ฐ๋ผ์:
๊ฐ์ฒด ์์ฑ๋ = ์ฑ๋ฅ ์ํฅ ์์
๊ฐ ๋๋ค.
Trade-off ๊ด์
๊ฐ์ฒด ์์ฑ ์ฅ์
- ์ฝ๋ ๋จ์ํ
- ๋ถ๋ณ ๊ฐ์ฒด ํ์ฉ ๊ฐ๋ฅ
- ์์ ์ฑ ์ฆ๊ฐ
๋จ์
- GC ์ฆ๊ฐ
- ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ ์ฆ๊ฐ
- CPU ๋น์ฉ ์ฆ๊ฐ
์ฆ:
โ์์ ์ฑ vs ์ฑ๋ฅโ
Trade-off ์กด์ฌ.
๋ฉด์ ๊ผฌ๋ฆฌ ์ง๋ฌธ
์์ฃผ ๋์ค๋ ์ง๋ฌธ:
- ๊ฐ์ฒด๋ ์ด๋์ ์ ์ฅ๋๋๊ฐ?
- Stack๊ณผ Heap ์ฐจ์ด๋?
- ์ Heap์ ๊ณต์ ๋ฉ๋ชจ๋ฆฌ์ธ๊ฐ?
- static ๋ณ์๋ ์ด๋์ ์ ์ฅ๋๋๊ฐ?
- GC Root๋?
- ์ Reachability ๋ฐฉ์ ์ฌ์ฉํ๋๊ฐ?
- ๊ฐ์ฒด ์์ฑ ๋น์ฉ์ด ์ ์ค์ํ๊ฐ?
์ข์ ๋ต๋ณ ์์
graph TD
A[new User ํธ์ถ] --> B[ClassLoader ํ์ธ]
B --> C[Heap ๊ฐ์ฒด ์์ฑ]
C --> D[์์ฑ์ ํธ์ถ]
D --> E[Stack ์ฐธ์กฐ ์ ์ฅ]
E --> F[GC Root ์ฐ๊ฒฐ]
F --> G[์ฐธ์กฐ ์ ๊ฑฐ ์ GC ๋์]
Java์์ ๊ฐ์ฒด ์์ฑ ์ ๋จผ์ ํด๋์ค ๋ก๋ฉ ์ฌ๋ถ๋ฅผ ํ์ธํฉ๋๋ค. ์ดํ Heap ์์ญ์ ๊ฐ์ฒด ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ๋นํ๊ณ , ์์ฑ์๋ฅผ ํธ์ถํฉ๋๋ค. ์ฐธ์กฐ ๋ณ์๋ Stack์ ์ ์ฅ๋๋ฉฐ, ๊ฐ์ฒด๋ GC Root๋ก๋ถํฐ ๋๋ฌ ๋ถ๊ฐ๋ฅํด์ง๋ฉด GC ๋์์ด ๋ฉ๋๋ค.
์ ๋๊น์ง ์ค๋ช ๊ฐ๋ฅํ๋ฉด ์๋นํ ์ข์ ๋ต๋ณ์ด๋ค.
ํ์ ์์ ํนํ ์ค์ํ ํฌ์ธํธ
์ค๋ฌด์์๋:
- ๊ฐ์ฒด ์์ฑ๋
- GC ๋น๋
- ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋
์ด ์ฑ๋ฅ๊ณผ ์ง์ ์ฐ๊ฒฐ๋๋ค.
ํนํ: ๋๋ ํธ๋ํฝ ํ๊ฒฝ์์๋:
โ๋ถํ์ํ ๊ฐ์ฒด ์์ฑ ์ค์ด๊ธฐโ
๊ฐ ์ฑ๋ฅ ์ต์ ํ ํต์ฌ ์ค ํ๋๋ค.
ํต์ฌ ์์ฝ
ํต์ฌ์ ๋ค์์ด๋ค.
- ๊ฐ์ฒด๋ Heap์ ์ ์ฅ๋๋ค
- ์ฐธ์กฐ ๋ณ์๋ Stack์ ์ ์ฅ๋๋ค
- static์ Method Area์ ์ ์ฅ๋๋ค
- GC๋ Reachability ๊ธฐ๋ฐ์ผ๋ก ๋์ํ๋ค
- ๊ฐ์ฒด ์์ฑ๋์ ์ฑ๋ฅ๊ณผ ์ง๊ฒฐ๋๋ค
ํนํ ์ค์ํ ๊ฑด:
โ๊ฐ์ฒด ์์ฑ โ ๋ฉ๋ชจ๋ฆฌ โ GC โ ์ฑ๋ฅโ
ํ๋ฆ์ ์ฐ๊ฒฐํด์ ์ดํดํ๋ ๊ฒ์ด๋ค.