week 3 yongseon - GANGNAM-JAVA/JAVA-STUDY GitHub Wiki

JAVA

Java8์˜ heap ๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š” ๊ทธ๋ฆฌ๊ณ  ํž™์˜์—ญ๊ณผ ์Šคํƒ์˜์—ญ์— ๋Œ€ํ•ด์„œ ์„ค๋ช…ํ•˜์‹œ์˜ค

์œ„ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด JDK7๊นŒ์ง€ ์‚ฌ์šฉ๋œ Permanent General(PermGen) Space๊ฐ€ Oracle์˜ ์ฃผ๋„ํ•˜์— ์ œ๊ฑฐ๋œ ๊ฒƒ์ด ํฐ ํŠน์ง• ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค.

Metaspace : ์ƒˆ๋กœ์šด ๋ฉ”๋ชจ๋ฆฌ ์ €์žฅ์†Œ์˜ ํƒ„์ƒ

JDK8 HotSpot JVM์˜ ๊ฒฝ์šฐ, ์žฌ์‚ฌ์šฉ์„ฑ์„ ์œ„ํ•œ ๊ฐ์ฒด์— ๋Œ€ํ•œ metadata๋ฅผ Metaspace๋ผ๊ณ  ๋ถˆ๋ฆฌ์šฐ๋Š” Native Memory์— ์ €์žฅํ•˜๊ฒŒ ๋˜์–ด OS๊ฐ€ ์ž๋™์œผ๋กœ ํฌ๊ธฐ๋ฅผ ์กฐ์ ˆํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ์กด๊ณผ ๋น„๊ตํ•ด ํฐ ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋กœ ์ธํ•ด Perm ์˜์—ญ ํฌ๊ธฐ๋กœ ์ธํ•œ java.lang.OutOfMemoryError : PermGen Space๋ฅผ ๋” ๋ณด๊ธฐ ํž˜๋“ค์–ด ์กŒ๊ณ , ๋” ์ด์ƒ tunning๊ณผ monitoring์„ ํ†ตํ•ด์„œ ์ด๋Ÿฌํ•œ memory space๋ฅผ ์กฐ์ ˆํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€๋งŒ, ์ด๋Ÿฌํ•œ ๋ณ€ํ™”๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์•ˆ๋ณด์ด๊ฒŒ ์„ค์ •์ด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์šฐ๋ฆฌ๋Š” ์ด ์ƒˆ๋กœ์šด meta memory์— ๋Œ€ํ•œ ์กฑ์ ์„ ์—ฌ์ „ํžˆ ์‚ดํŽด๋ณผ ํ•„์š”์„ฑ์€ ์กด์žฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์š”์•ฝ

PermGen space situation

  • memory space๋Š” ์™„๋ฒฝํ•˜๊ฒŒ ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.
  • PermSize์™€ MaxPermSize JVM argument๋Š” ๋ฌด์‹œ๋˜๋ฉฐ, ์‹œ์ž‘๋ ๋•Œ ๊ฒฝ๊ณ ๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

Metaspace memory allocation model

  • class์˜ metadata๋Š” ๊ฑฐ์˜ ๋Œ€๋ถ€๋ถ„ native memory์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.
  • class์˜ metadata๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ klasses๋“ค์€ ๋ชจ๋‘ ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.

Metaspace capacity

  • ๊ธฐ๋ณธ์ ์œผ๋กœ metaspace๋Š” native memory๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์—, OS์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ memory ์˜์—ญ ๋ชจ๋‘๋ฅผ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  • ์ƒˆ๋กœ์šด Flag(MaxMetaSpaceSize)๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” class metadata๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ์ตœ๋Œ€ํ•œ์˜ memory size๋ฅผ ์ •ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ์— Flag๋ฅผ ์„ค์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด, Metaspace๋Š” application์˜ ๋™์ž‘์— ๋”ฐ๋ผ ๊ฐ€๋ณ€์ ์œผ๋กœ ๋™์ž‘ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

Metaspace garbage collection

  • dead class์™€ classloader์˜ GC๋Š” MaxMetaspaceSize์— ๋„๋‹ฌํ•˜๋ฉด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
  • Metaspace์˜ tuning๊ณผ monitoring์€ GC์˜ ํšŸ์ˆ˜์™€ ์ง€์—ญ์„ ์ œํ•œํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ์ž‘์—…์ž…๋‹ˆ๋‹ค. ๊ณผ๋„ํ•œ Metaspace GC๋Š” classloader์˜ memory leak ๋˜๋Š” ์ ํ•ฉํ•˜์ง€ ์•Š์€ Application์˜ memory size๋ฅผ ์ดˆ๋ž˜ํ•ฉ๋‹ˆ๋‹ค.

Java heap space impact

  • ์—ฌ๋Ÿฌ ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ๋“ค์€ Java Heap space๋กœ ์ €์žฅ ์˜์—ญ์ด ์ด๋™๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ตญ ๊ธฐ์กด JDK7์—์„œ JDK8๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ๋ฅผ ํ•˜๋Š” ๊ฒฝ์šฐ, Java Heap memory๋ฅผ ์ฆ๊ฐ€์‹œํ‚ฌ ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

Metaspace monitoring

  • metaspace ์‚ฌ์šฉ๋Ÿ‰์€ GC log output์„ ํ†ตํ•ด์„œ ํ™•์ธ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  • Jstat * JVirtualVM ์€ ์•„์ง metaspace๋ฅผ monitoring ํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ์•„์ง ์˜ˆ์ „ PermGen space reference๋ฅผ ํ™•์ธํ•˜๋„๋ก ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

Heap Space

Java Heap Space๋Š” Java Runtime์—์„œ Memory๋ฅผ Object ๋ฐ JRE Class์— ํ• ๋‹นํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ๋•Œ๋งˆ๋‹ค ํ•ญ์ƒ Heap Space์— ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค.

Garbage Collection์€ Heap Memory์—์„œ ์‹คํ–‰๋˜์–ด ์ฐธ์กฐ๊ฐ€ ์—†๋Š” Object๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” Memory๋ฅผ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค. Heap Space์—์„œ ์ƒ์„ฑ ๋œ ๋ชจ๋“  ๊ฐœ์ฒด๋Š” ์ „์—ญ ์•ก์„ธ์Šค ๊ถŒํ•œ์„ ๊ฐ€์ง€๋ฉฐ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์˜ ์–ด๋Š ๊ณณ์—์„œ๋‚˜ ์ฐธ์กฐ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Stack Memory

Java Stack Memory๋Š” Thread ์‹คํ–‰์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” ์ˆ˜๋ช…์ด ์งง์€ Method ๋ณ„ ๊ฐ’๊ณผ Method์—์„œ ์ฐธ์กฐ๋˜๋Š” Heap์˜ ๋‹ค๋ฅธ Object์— ๋Œ€ํ•œ ์ฐธ์กฐ๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

Stack Memory๋Š” ํ•ญ์ƒ LIFO(Last-In-First-Out) ์ˆœ์„œ๋กœ ์ฐธ์กฐ๋ฉ๋‹ˆ๋‹ค. Method๊ฐ€ ํ˜ธ์ถœ ๋  ๋•Œ๋งˆ๋‹ค Method๊ฐ€ ๋กœ์ปฌ ๊ธฐ๋ณธ ๊ฐ’์„ ๋ณด์œ ํ•˜๊ณ  Method์˜ ๋‹ค๋ฅธ Object์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ๋ณด์œ  ํ•  ์ˆ˜ ์žˆ๋„๋ก Stack Memory์— ์ƒˆ ๋ธ”๋ก์ด ์ž‘์„ฑ๋ฉ๋‹ˆ๋‹ค.

Method๊ฐ€ ์ข…๋ฃŒ๋˜์ž๋งˆ์ž ๋ธ”๋ก์€ ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ณ  ๋‹ค์Œ Method์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. Stack Memory ํฌ๊ธฐ๋Š” Heap Memory์— ๋น„ํ•ด ๋งค์šฐ ์ž‘์Šต๋‹ˆ๋‹ค.

Java ํ”„๋กœ๊ทธ๋žจ์˜ ํž™ ๋ฐ ์Šคํƒ ๋ฉ”๋ชจ๋ฆฌ

public class Memory {
    public static void main(String[] args) { // Line 1
        int i=1; // Line 2
        Object obj = new Object(); // Line 3
        Memory mem = new Memory(); // Line 4
            mem.foo(obj); // Line 5
        } // Line 9
        
        private void foo(Object param) { // Line 6
            String str = param.toString(); //// Line 7
            System.out.println(str);
        } // Line 8
    }
}

์•„๋ž˜ ์ด๋ฏธ์ง€๋Š” ์œ„ ํ”„๋กœ๊ทธ๋žจ์„ ์ฐธ์กฐํ•œ ์Šคํƒ ๋ฐ ํž™ ๋ฉ”๋ชจ๋ฆฌ์™€ ๊ธฐ๋ณธ, ๊ฐ์ฒด ๋ฐ ์ฐธ์กฐ ๋ณ€์ˆ˜๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

  • ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•˜๋ฉด ๋ชจ๋“  ๋Ÿฐํƒ€์ž„ ํด๋ž˜์Šค๋ฅผ ํž™ ๊ณต๊ฐ„์œผ๋กœ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค. main() ๋ฉ”์†Œ๋“œ๊ฐ€ 1ํ–‰์—์„œ ๋ฐœ๊ฒฌ๋˜๋ฉด Java ๋Ÿฐํƒ€์ž„์€ main() ๋ฉ”์†Œ๋“œ ์Šค๋ ˆ๋“œ์—์„œ ์‚ฌ์šฉํ•  ์Šคํƒ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

  • Line 2์—์„œ ๋กœ์ปฌ ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“ค๊ณ  ์žˆ์œผ๋ฏ€๋กœ main()๋ฉ”์†Œ๋“œ์˜ ์Šคํƒ ๋ฉ”๋ชจ๋ฆฌ์— ๋งŒ๋“ค์–ด ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.

  • Line 3์—์„œ๋Š” ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํž™ ๋ฉ”๋ชจ๋ฆฌ์— ์ƒ์„ฑ๋˜๋ฉฐ ์Šคํƒ ๋ฉ”๋ชจ๋ฆฌ์—๋Š” ์ด์— ๋Œ€ํ•œ ์ฐธ์กฐ๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. Line 4์—์„œ Memory ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ๋•Œ ๋น„์Šทํ•œ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋ฐœ์ƒ๋ฉ๋‹ˆ๋‹ค.

  • Line 5์—์„œ foo() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์Šคํƒ ๋งจ ์œ„์— ์žˆ๋Š” ๋ธ”๋ก์ด foo() ๋ฉ”์†Œ๋“œ์—์„œ ์‚ฌ์šฉ๋˜๋„๋ก ์ž‘์„ฑ๋ฉ๋‹ˆ๋‹ค. Java๋Š” ๊ฐ’์œผ๋กœ ์ „๋‹ฌ๋˜๋ฏ€๋กœ Line 66์˜ foo() ์Šคํƒ ๋ธ”๋ก์— Object์— ๋Œ€ํ•œ ์ƒˆ๋กœ์šด ์ฐธ์กฐ๊ฐ€ ์ž‘์„ฑ๋ฉ๋‹ˆ๋‹ค.

  • ๋ฌธ์ž์—ด์€ Line 7์—์„œ ๋งŒ๋“ค์–ด์ง€๊ณ , ํž™ ๊ณต๊ฐ„์˜ String Pool์— ๋“ค์–ด๊ฐ€๊ณ  ์ด์— ๋Œ€ํ•œ foo() ์Šคํƒ ๊ณต๊ฐ„์— ์ฐธ์กฐ๊ฐ€ ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค.

  • foo() ๋ฉ”์†Œ๋“œ๋Š” Line 8์—์„œ ์ข…๋ฃŒ๋˜๋ฉฐ, ์ด๋•Œ ์Šคํƒ์˜ foo()์— ํ• ๋‹น ๋œ ๋ฉ”๋ชจ๋ฆฌ ๋ธ”๋ก์€ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ด์ง‘๋‹ˆ๋‹ค.

  • Line 9์—์„œ main() ๋ฉ”์†Œ๋“œ๊ฐ€ ์ข…๋ฃŒ๋˜๊ณ  main() ๋ฉ”์†Œ๋“œ์— ๋Œ€ํ•ด ์ž‘์„ฑ๋œ ์Šคํƒ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์†์ƒ๋ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ํ”„๋กœ๊ทธ๋žจ์€ ์ด ํ–‰์—์„œ ์ข…๋ฃŒ๋˜๋ฏ€๋กœ Java Runtime์€ ๋ชจ๋“  ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์ œํ•˜๊ณ  ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰์„ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค.

ํž™ ๋ฉ”๋ชจ๋ฆฌ์™€ ์Šคํƒ ๋ฉ”๋ชจ๋ฆฌ์˜ ์ฐจ์ด์ 

  1. ํž™ ๋ฉ”๋ชจ๋ฆฌ๋Š” ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์˜ ๋ชจ๋“  ๋ถ€๋ถ„์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ฐ˜๋ฉด ์Šคํƒ ๋ฉ”๋ชจ๋ฆฌ๋Š” ํ•˜๋‚˜์˜ ์‹คํ–‰ ์Šค๋ ˆ๋“œ์—์„œ๋งŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

  2. ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ ๋  ๋•Œ๋งˆ๋‹ค ํ•ญ์ƒ ํž™ ๊ณต๊ฐ„์— ์ €์žฅ๋˜๋ฉฐ ์Šคํƒ ๋ฉ”๋ชจ๋ฆฌ์—๋Š” ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ฐธ์กฐ๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ์Šคํƒ ๋ฉ”๋ชจ๋ฆฌ์—๋Š” ๋กœ์ปฌ ํ”„๋ฆฌ๋ฏธํ‹ฐ๋ธŒ ๋ณ€์ˆ˜์™€ ํž™ ๊ณต๊ฐ„์˜ ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ฐธ์กฐ ๋ณ€์ˆ˜ ๋งŒ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

  3. ํž™์— ์ €์žฅ๋œ ๊ฐ์ฒด๋Š” ์ „์—ญ ์ ์œผ๋กœ ์•ก์„ธ์Šค ํ•  ์ˆ˜์žˆ๋Š” ๋ฐ˜๋ฉด ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋Š” ์Šคํƒ ๋ฉ”๋ชจ๋ฆฌ์— ์•ก์„ธ์Šค ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

  4. ์Šคํƒ์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋Š” LIFO ๋ฐฉ์‹์œผ๋กœ ์ˆ˜ํ–‰๋˜๋Š” ๋ฐ˜๋ฉด, ํž™ ๋ฉ”๋ชจ๋ฆฌ์—์„œ๋Š” ์ „์ฒด์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋ฏ€๋กœ ๋” ๋ณต์žกํ•ฉ๋‹ˆ๋‹ค. ํž™ ๋ฉ”๋ชจ๋ฆฌ๋Š” Java Garbage Collection ์—์„œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ Young-Generation, Old-Generation ๋“ฑ์œผ๋กœ ๊ตฌ๋ถ„๋ฉ๋‹ˆ๋‹ค.

  5. ์Šคํƒ ๋ฉ”๋ชจ๋ฆฌ๋Š” ์ˆ˜๋ช…์ด ์งง์€ ๋ฐ˜๋ฉด ํž™ ๋ฉ”๋ชจ๋ฆฌ๋Š” ์‹œ์ž‘๋ถ€ํ„ฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰์ด ๋๋‚  ๋•Œ๊นŒ์ง€ ์ง€์†๋ฉ๋‹ˆ๋‹ค. -Xms ๋ฐ -Xmx JVM ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ์‹œ์ž‘ ํฌ๊ธฐ ๋ฐ ์ตœ๋Œ€ ํž™ ๋ฉ”๋ชจ๋ฆฌ ํฌ๊ธฐ๋ฅผ ์ •์˜ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค . -Xss ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์Šคํƒ ๋ฉ”๋ชจ๋ฆฌ ํฌ๊ธฐ๋ฅผ ์ •์˜ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  6. ์Šคํƒ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๊ฐ€๋“ ์ฐจ๋ฉด Java ๋Ÿฐํƒ€์ž„์ด ๋ฐœ์ƒ java.lang.StackOverFlowErrorํ•˜์ง€๋งŒ ํž™ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๊ฐ€๋“ ์ฐจ๋ฉด java.lang.OutOfMemoryError: Java Heap Space์˜ค๋ฅ˜ ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์Šคํƒ ๋ฉ”๋ชจ๋ฆฌ ํฌ๊ธฐ๋Š” ํž™ ๋ฉ”๋ชจ๋ฆฌ์™€ ๋น„๊ตํ•  ๋•Œ ๋งค์šฐ ์ž‘์Šต๋‹ˆ๋‹ค. ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น (LIFO)์˜ ๋‹จ์ˆœ์„ฑ์œผ๋กœ ์ธํ•ด ์Šคํƒ ๋ฉ”๋ชจ๋ฆฌ๋Š” ํž™ ๋ฉ”๋ชจ๋ฆฌ์™€ ๋น„๊ตํ•  ๋•Œ ๋งค์šฐ ๋น ๋ฆ…๋‹ˆ๋‹ค.

์ž๋ฐ”8์—์„œ ์†Œ๊ฐœ๋œ ๋žŒ๋‹ค์‹๊ณผ ๋ฉ”์†Œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์„ค๋ช…ํ•˜๋ผ.

๋žŒ๋‹ค

๋ฉ”์†Œ๋“œ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋Š” ์ต๋ช… ํ•จ์ˆ˜(Anonymous Function)๋ฅผ ๋‹จ์ˆœํ™”ํ•œ ๊ฒƒ์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋žŒ๋‹ค ํ‘œํ˜„์‹์—๋Š” ์ด๋ฆ„์€ ์—†์ง€๋งŒ, ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฆฌ์ŠคํŠธ, ๋ฐ”๋””, ๋ฐ˜ํ™˜ ํ˜•์‹, ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์˜ˆ์™ธ ๋ฆฌ์ŠคํŠธ๋Š” ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋žŒ๋‹ค์˜ ํŠน์ง•

  • ์ต๋ช…

๋ณดํ†ต์˜ ๋ฉ”์†Œ๋“œ์™€ ๋‹ฌ๋ฆฌ ์ด๋ฆ„์ด ์—†์œผ๋ฏ€๋กœ ์ต๋ช…์ด๋ผ ํ‘œํ˜„ํ•ฉ๋‹ˆ๋‹ค.

  • ํ•จ์ˆ˜

๋žŒ๋‹ค๋Š” ๋ฉ”์†Œ๋“œ์ฒ˜๋Ÿผ ํŠน์ • ํด๋ž˜์Šค์— ์ข…์†๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ํ•จ์ˆ˜๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ฉ”์†Œ๋“œ์ฒ˜๋Ÿผ ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฆฌ์ŠคํŠธ, ๋ฐ˜ํ™˜ ํ˜•์‹, ๊ฐ€๋Šฅํ•œ ์˜ˆ์™ธ ๋ฆฌ์ŠคํŠธ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

  • ์ „๋‹ฌ

๋žŒ๋‹ค ํ‘œํ˜„์‹์„ ๋ฉ”์†Œ๋“œ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•˜๊ฑฐ๋‚˜ ๋ณ€์ˆ˜๋กœ ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๊ฐ„๊ฒฐ์„ฑ

์ต๋ช… ํด๋ž˜์Šค์ฒ˜๋Ÿผ ๋งŽ์€ ์ž์งˆ๊ตฌ๋ ˆํ•œ ์ฝ”๋“œ๋ฅผ ๊ตฌํ˜„ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋žŒ๋‹ค์˜ ๊ตฌ์„ฑ

ex) (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());

  • ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฆฌ์ŠคํŠธ

Comparator์˜ compare ๋ฉ”์†Œ๋“œ ํŒŒ๋ผ๋ฏธํ„ฐ(์‚ฌ๊ณผ ๋‘๊ฐœ)

  • ํ™”์‚ดํ‘œ

ํ™”์‚ดํ‘œ(->)๋Š” ๋žŒ๋‹ค์˜ ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฆฌ์ŠคํŠธ์™€ ๋ฐ”๋””๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค.

  • ๋ฐ”๋””

๋‘ ์‚ฌ๊ณผ์˜ ๋ฌด๊ฒŒ๋ฅผ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค. ๋žŒ๋‹ค์˜ ๋ฐ˜ํ™˜๊ฐ’์— ํ•ด๋‹นํ•˜๋Š” ํ‘œํ˜„์‹์ž…๋‹ˆ๋‹ค.

๋žŒ๋‹ค ํ‘œํ˜„์‹

  • () -> {}
  • () -> "Seoul"
  • () -> {return "Seoul"}
  • (Integer a) -> {return "Seoul" + a;}

return์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐ˜๋“œ์‹œ ์ค‘๊ด„ํ˜ธ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋žŒ๋‹ค๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ์—๋Š” ๋ฐ˜๋“œ์‹œ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค

ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์ •ํ™•ํžˆ ํ•˜๋‚˜์˜ ์ถ”์ƒ ๋ฉ”์†Œ๋“œ๋ฅผ ์ง€์ •ํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค์ž…๋‹ˆ๋‹ค. Java 8 ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค๊ณ„์ž๋“ค์€ java.util.function ํŒจํ‚ค์ง€๋กœ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์ƒˆ๋กœ์šด ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

  • Predicate : test ๋ผ๋Š” ์ถ”์ƒ ๋ฉ”์†Œ๋“œ๋ฅผ ์ •์˜ํ•˜๋ฉฐ test๋Š” ์ œ๋„ค๋ฆญ ํ˜•์‹ T์˜ ๊ฐ์ฒด๋ฅผ ์ธ์ˆ˜๋กœ ๋ฐ›์•„ boolean์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋กœ ์ •์˜ํ•  ํ•„์š” ์—†์ด ๋ฐ”๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด ํŠน์ง•์ž…๋‹ˆ๋‹ค.

ex) Predicate example source

@FunctionalInterface

public interface Predicate<T> {

    boolean test(T t);

}

public <T> List<T> filter(List<T> list, Predicate<T> p) {

    List<T> results = new ArrayList<>();

    for(T t : list) {

        if (p.test(t)) {

            results.add(t);

        }

    }

}
Predicate<String> nonEmptyStringPredicate = (String s) -> !s.isEmpty();
List<String> nonEmpty = filter(listOfStrings, nonEmptyStringPredicate);
  • Consumer : ์ œ๋„ค๋ฆญ ํ˜•์‹ T ๊ฐ์ฒด๋ฅผ ๋ฐ›์•„์„œ void๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” accept ๋ผ๋Š” ์ถ”์ƒ ๋ฉ”์†Œ๋“œ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. T ํ˜•์‹์˜ ๊ฐ์ฒด๋ฅผ ์ธ์ˆ˜๋กœ ๋ฐ›์•„์„œ ์–ด๋–ค ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์‹ถ์„ ๋•Œ Consumer ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ex) Consumer example source

@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);
}

public <T> void forEach(List<T> list, Consumer<T> c) {
    for(T t : list) {
        c.accept(t);
    }
}
forEach(
    Arrays.asList(1, 2, 3, 4, 5);
    (Integer i) -> System.out.println(i);
);
  • Function<T, R> : ์ œ๋„ค๋ฆญ ํ˜•์‹ T๋ฅผ ์ธ์ˆ˜๋กœ ๋ฐ›์•„์„œ ์ œ๋„ค๋ฆญ ํ˜•์‹ R ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ถ”์ƒ ๋ฉ”์†Œ๋“œ apply๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ์ž…๋ ฅ์„ ์ถœ๋ ฅ์œผ๋กœ ๋งคํ•‘ํ•˜๋Š” ๋žŒ๋‹ค๋ฅผ ์ •์˜ํ•  ๋•Œ Function ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์˜ˆ๋ฅผ ๋“ค๋ฉด ์‚ฌ๊ณผ์˜ ๋ฌด๊ฒŒ ์ •๋ณด๋ฅผ ์ถ”์ถœํ•˜๊ฑฐ๋‚˜ ๋ฌธ์ž์—ด์„ ๊ธธ์ด์™€ ๋งคํ•‘).

ex) Function example source

@FunctionalInterface
public interface Function<T, R> {
    R apply(T t);
}

public <T, R> List<R> map(List<T> list, FUnction<T, R> f) {
    List<R> result = new ArrayList<>();
    for(T t : list) {
        result.add(f.apply(t));
    }
    return result;
}

// [7, 2, 6]
List<Integer> l = map(
    Arrays.asList("lambdas", "in", "action"),
    (String s) -> s.length() // Function์˜ apply ๋ฉ”์†Œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋žŒ๋‹ค
);
  • Supplier : ์ธ์ˆ˜ ์—†์ด ๊ฐ’์„ ๋ฆฌํ„ดํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

ex) Supplier example source

@FunctionalInterface
public interface Supplier<T> {
    T get();
}

Supplier<Integer> solution = () -> 42;
System.out.println(solution.get());

์œ„์˜ ๋„ค ๊ฐœ์˜ ์ œ๋„ค๋ฆญ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค ์™ธ์— ํŠนํ™”๋œ ํ˜•์‹์˜ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž๋ฐ”์˜ ๋ชจ๋“  ํ˜•์‹์€ ์ฐธ์กฐํ˜• ์•„๋‹ˆ๋ฉด ๊ธฐ๋ณธํ˜•์— ํ•ด๋‹นํ•˜์ง€๋งŒ ์ œ๋„ค๋ฆญ์˜ ๋‚ด๋ถ€๊ตฌํ˜„ ๋•Œ๋ฌธ์— ์ œ๋„ค๋ฆญ ํŒŒ๋ผ๋ฏธํ„ฐ์—๋Š” ์ฐธ์กฐํ˜•๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž๋ฐ”์—์„œ๋Š” ๊ธฐ๋ณธํ˜•์„ ์ฐธ์กฐํ˜•์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋ฉฐ ์ด ๊ธฐ๋Šฅ์„ ๋ฐ•์‹ฑ์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์ฐธ์กฐํ˜•์„ ๊ธฐ๋ณธํ˜•์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐ˜๋Œ€ ๋™์ž‘์„ ์–ธ๋ฐ•์‹ฑ์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ํŠน์ • ํ˜•์‹์„ ์ž…๋ ฅ์œผ๋กœ ๋ฐ›๋Š” ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ด๋ฆ„ ์•ž์—๋Š” DoublePredicate, IntConsumer, IntFunction ์ฒ˜๋Ÿผ ํ˜•์‹๋ช…์ด ๋ถ™์Šต๋‹ˆ๋‹ค.

@FunctionalInterface

@FunctionalInterface๋Š” ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค์ž„์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ์–ด๋…ธํ…Œ์ด์…˜์ž…๋‹ˆ๋‹ค. @FunctionalInterface๋กœ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์„ ์–ธํ–ˆ์ง€๋งŒ ์‹ค์ œ๋กœ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์•„๋‹ˆ๋ฉด ์ปดํŒŒ์ผ ํƒ€์ž„ ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค. ์–ด๋–ค ์ธํ„ฐํŽ˜์ด์Šค๋“ค์€ ์šฐ์—ฐํžˆ ํ•จ์ˆ˜ํ˜•์œผ๋กœ ์ •์˜๋  ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, Functional Interface๋“ค์ด ๋ชจ๋‘ @FunctionalInterface ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ์„ ์–ธ๋  ํ•„์š”๋„ ์—†๊ณ  ๊ทธ๋ ‡๊ฒŒ ํ•˜๋Š” ๊ฒƒ์ด ๋ฐ”๋žŒ์งํ•˜์ง€๋„ ์•Š์Šต๋‹ˆ๋‹ค. ์ฆ‰, @FunctionalInterface๋Š” ์ž‘์„ฑํ•œ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ Functional Interface์ž„์„ ํ™•์‹คํžˆ ํ•˜๊ธฐ ์›ํ•  ๋•Œ์—๋งŒ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

๋ฉ”์†Œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค

  • ๋ฉ”์†Œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์ด์šฉํ•˜๋ฉด ๊ธฐ์กด์˜ ๋ฉ”์†Œ๋“œ ์ •์˜๋ฅผ ์žฌํ™œ์šฉํ•ด์„œ ๋žŒ๋‹ค์ฒ˜๋Ÿผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋žŒ๋‹ค ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•˜๋Š”๊ฒƒ๋ณด๋‹ค ๊ฐ€๋…์„ฑ์ด ์ข‹๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฉ”์†Œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•

  1. ์ •์  ๋ฉ”์†Œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค

ex) Integer์˜ parseInt ๋ฉ”์†Œ๋“œ๋Š” Integer::parseInt๋กœ ํ‘œํ˜„๊ฐ€๋Šฅ

  1. ๋‹ค์–‘ํ•œ ํ˜•์‹์˜ ์ธ์Šคํ„ด์Šค ๋ฉ”์†Œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค

ex) String์˜ length ๋ฉ”์†Œ๋“œ๋Š” String::length๋กœ ํ‘œํ˜„๊ฐ€๋Šฅ

  1. ๊ธฐ์กด ๊ฐ์ฒด์˜ ์ธ์Šคํ„ด์Šค ๋ฉ”์†Œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค

ex) Transaction ๊ฐ์ฒด๋ฅผ ํ• ๋‹น๋ฐ›์€ expensiveTransaction ์ง€์—ญ ๋ณ€์ˆ˜๊ฐ€ ์žˆ๊ณ , Transaction ๊ฐ์ฒด์—๋Š” getValue ๋ฉ”์†Œ๋“œ๊ฐ€ ์žˆ๋‹ค๋ฉด,

์ด๋ฅผ expensiveTransaction::getValue๋ผ๊ณ  ํ‘œํ˜„๊ฐ€๋Šฅ

  1. ์ƒ์„ฑ์ž ๋ ˆํผ๋Ÿฐ์Šค

ex) Apple(Integer weight)๋ผ๋Š” ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ ๊ฐ–๋Š” ์ƒ์„ฑ์ž๋Š” Function ์ธํ„ฐํŽ˜์ด์Šค์˜ ์‹œ๊ทธ๋‹ˆ์ฒ˜์™€ ๊ฐ™์•„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Function<Integer, Apple> c = Apple::new; Apple apple = c.apply(110); // Function์˜ apply ๋ฉ”์†Œ๋“œ์— ๋ฌด๊ฒŒ๋ฅผ ์ธ์ˆ˜๋กœ ํ˜ธ์ถœํ•ด์„œ ์ƒˆ๋กœ์šด Apple ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

checked-exception VS unchecked-exception ์ฐจ์ด์ ์„ ์„ค๋ช…ํ•ด๋ณด์„ธ์š”.

RuntimeException์„ ์ƒ์†ํ•˜์ง€ ์•Š๋Š” ํด๋ž˜์Šค๋Š” Checked Exception RuntimeException์„ ์ƒ์†ํ•œ ํด๋ž˜์Šค๋Š” Unchecked Exceptin์œผ๋กœ ๋ถ„๋ฅ˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Checked-Exception๊ณผ Unchecked-Exception์˜ ๊ฐ€์žฅ ๋ช…ํ™•ํ•œ ๊ตฌ๋ถ„ ๊ธฐ์ค€์€ '๊ผญ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์•ผ ํ•˜๋Š๋ƒ'์ž…๋‹ˆ๋‹ค. Checked-Exception์ด ๋ฐœ์ƒํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋Š” ๋ฉ”์†Œ๋“œ๋ผ๋ฉด ๋ฐ˜๋“œ์‹œ ๋กœ์ง์„ try/catch๋กœ ๊ฐ์‹ธ๊ฑฐ๋‚˜ throw๋กœ ๋˜์ ธ์„œ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ฐ˜๋ฉด์— Unchecked-Exception์€ ๋ช…์‹œ์ ์ธ ์˜ˆ์™ธ์ฒ˜๋ฆฌ๋ฅผ ํ•˜์ง€ ์•Š์•„๋„ ๋ฉ๋‹ˆ๋‹ค. ์ด ์˜ˆ์™ธ๋Š” ํ”ผํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ถ€์ฃผ์˜ํ•ด์„œ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋Œ€๋ถ€๋ถ„์ด๊ณ , ๋ฏธ๋ฆฌ ์˜ˆ์ธกํ•˜์ง€ ๋ชปํ–ˆ๋˜ ์ƒํ™ฉ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์˜ˆ์™ธ๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ตณ์ด ๋กœ์ง์œผ๋กœ ์ฒ˜๋ฆฌ๋ฅผ ํ•  ํ•„์š”๊ฐ€ ์—†๋„๋ก ๋งŒ๋“ค์–ด์ ธ ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ์˜ˆ์™ธ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ์‹œ์ ์—์„œ๋„ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ์ปดํŒŒ์ผ ๋‹จ๊ณ„์—์„œ ๋ช…ํ™•ํ•˜๊ฒŒ Exception ์ฒดํฌ๊ฐ€ ๊ฐ€๋Šฅํ•œ ๊ฒƒ์„ Checked-Exception์ด๋ผ ํ•˜๋ฉฐ, ์‹คํ–‰๊ณผ์ • ์ค‘ ์–ด๋–ค ํŠน์ • ๋…ผ๋ฆฌ์— ์˜ํ•ด ๋ฐœ๊ฒฌ๋˜๋Š” Exception์„ Unchecked-Exception์ด๋ผ ํ•ฉ๋‹ˆ๋‹ค.

ํ•œ๊ฐ€์ง€ ๋” ์ธ์ง€ํ•˜๊ณ  ์žˆ์–ด์•ผ ํ•  ๊ฒƒ์€ ์˜ˆ์™ธ๋ฐœ์ƒ ์‹œ ํŠธ๋žœ์žญ์…˜์˜ rollback ์—ฌ๋ถ€์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ Checked-Exception์€ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ํŠธ๋žœ์žญ์…˜์„ rollback ํ•˜์ง€ ์•Š๊ณ  ์˜ˆ์™ธ๋ฅผ ๋˜์ ธ์ค๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ Uncehcked-Exception์€ ์˜ˆ์™ธ ๋ฐœ์ƒ ์‹œ ํŠธ๋žœ์žญ์…˜์„ rollback ํ•œ๋‹ค๋Š” ์ ์—์„œ ์ฐจ์ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ•

์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ•์—๋Š” ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋‹ค๋ฅธ ์ž‘์—… ํ๋ฆ„์œผ๋กœ ์œ ๋„ํ•˜๋Š” ์˜ˆ์™ธ ๋ณต๊ตฌ์™€ ์ฒ˜๋ฆฌ ํ•˜์ง€ ์•Š๊ณ  ํ˜ธ์ถœํ•œ ์ชฝ์œผ๋กœ ๋˜์ ธ๋ฒ„๋ฆฌ๋Š” ์˜ˆ์™ธ์ฒ˜๋ฆฌ ํšŒํ”ผ, ๊ทธ๋ฆฌ๊ณ  ํ˜ธ์ถœํ•œ ์ชฝ์œผ๋กœ ๋˜์งˆ ๋•Œ ๋ช…ํ™•ํ•œ ์˜๋ฏธ๋ฅผ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค๋ฅธ ์˜ˆ์™ธ๋กœ ์ „ํ™˜ํ•˜์—ฌ ๋˜์ง€๋Š” ์˜ˆ์™ธ ์ „ํ™˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ์˜ˆ์™ธ ๋ณต๊ตฌ

     int try = TRY_CNT;
     
     while (try-- > 0) {
     
         try {
             
             // ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋Š” ์‹œ๋„
             
             return; // ์„ฑ๊ณต ์‹œ ๋ฆฌํ„ด
             
         } catch (Exception e) {
             
             // ๋กœ๊ทธ ์ถœ๋ ฅ, ์—๋Ÿฌ ์ฒ˜๋ฆฌ
             
         } finally {
             
             // ๋ฆฌ์†Œ์Šค ๋ฐ˜๋‚ฉ, ์ •๋ฆฌ
             
         }
         
     }
     
     throw new RetryFailedException(); // ์ตœ๋Œ€ ์žฌ์‹œ๋„ ํšŸ์ˆ˜๋ฅผ ๋„˜๊ธฐ๋ฉด ์ง์ ‘ ์˜ˆ์™ธ ๋ฐœ์ƒ
    

try์—์„œ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ์ง„ํ–‰ํ•˜๊ณ  ์˜ˆ์™ธ ๋ฐœ์ƒ์‹œ catch๋ฌธ์—์„œ ์ฒ˜๋ฆฌ, ๋ณต๊ตฌ ์‹œ๋„๋ฅผ ํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. finally๋Š” ์„ฑ๊ณต, ์‹คํŒจ์˜ ๋‘๊ฐ€์ง€ ๊ฒฝ์šฐ ๋ชจ๋‘ ์‹คํ–‰๋˜๋Š” ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค. ์˜ˆ์™ธ๋ณต๊ตฌ์˜ ํ•ต์‹ฌ์€ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ๋„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์ •์ƒ์ ์ธ ํ๋ฆ„์œผ๋กœ ์ง„ํ–‰๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

  1. ์˜ˆ์™ธ์ฒ˜๋ฆฌ ํšŒํ”ผ

     public void add() throws SQLException {
    
         ... // ๊ตฌํ˜„ ๋กœ์ง
    
     }
    

์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด throws๋ฅผ ํ†ตํ•ด ํ˜ธ์ถœํ•œ์ชฝ์œผ๋กœ ์˜ˆ์™ธ๋ฅผ ๋˜์ง€๊ณ  ๊ทธ ์ฒ˜๋ฆฌ๋ฅผ ํšŒํ”ผํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ˜ธ์ถœํ•œ ์ชฝ์—์„œ ์˜ˆ์™ธ๋ฅผ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•˜๋„๋ก ํ•˜๊ฑฐ๋‚˜, ํ•ด๋‹น ๋ฉ”์†Œ๋“œ์—์„œ ์ด ์˜ˆ์™ธ๋ฅผ ๋˜์ง€๋Š” ๊ฒƒ์ด ์ตœ์„ ์˜ ๋ฐฉ๋ฒ•์ด๋ผ๋Š” ํ™•์‹ ์ด ์žˆ์„ ๋•Œ๋งŒ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  1. ์˜ˆ์™ธ ์ „ํ™˜

     catch(SQLException e) {
    
         ...
    
         throw DuplicateUserIdException();
    
     }
    

์˜ˆ์™ธ์ „ํ™˜์€ ์œ„ ์ฝ”๋“œ์ฒ˜๋Ÿผ ์˜ˆ์™ธ๋ฅผ ์žก์•„์„œ ๋‹ค๋ฅธ ์˜ˆ์™ธ๋กœ ๋˜์ง€๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ˜ธ์ถœํ•œ ์ชฝ์—์„œ ์˜ˆ์™ธ๋ฅผ ๋ฐ›์•„์„œ ์ฒ˜๋ฆฌํ•  ๋•Œ ์ข€ ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ์ธ์ง€ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์–ด๋–ค ์˜ˆ์™ธ์ธ์ง€ ๋ถ„๋ช…ํ•ด์•ผ ์ฒ˜๋ฆฌ๊ฐ€ ์ˆ˜์›”ํ•ด์ง€๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

SPRING

@Service, @Component์˜ ์ฐจ์ด๋Š” ๋ฌด์—‡์ธ๊ฐ€?

@Service

  • ๋น„์ฆˆ๋‹ˆ์Šค ๋…ผ๋ฆฌ ๋ฐ ํ˜ธ์ถœ ๋ฉ”์†Œ๋“œ๋ฅผ ์ •์˜
  • ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๊ฐ€์ง€๊ณ  ์žˆ์Œ์„ ํ‘œํ˜„
  • Business Layer์— ์†ํ•จ -> ์ปจํŠธ๋กค๋Ÿฌ์™€ ๋ทฐ๋ฅผ ์—ฐ๊ฒฐ
  • ํ•„์š”ํ•  ๋•Œ ํŠน์ • ์˜ˆ์™ธ, ์˜ˆ์™ธ์ฒ˜๋ฆฌ๋ฅผ ์ถ”๊ฐ€ ํ•  ์ˆ˜ ์žˆ์Œ

@Component

  • ์ž๋™์œผ๋กœ ์Šค์บ”ํ•ด์„œ ๋“ฑ๋กํ•˜๊ณ  ์‹ถ์€ ๊ฒƒ๋“ค์„ ์œ„ํ•ด ์‚ฌ์šฉ
  • @Component์˜ ๊ตฌ์ฒดํ™”๋œ ํ˜•ํƒœ๋กœ @Controller, @Service, @Controller ๋“ฑ์ด ์žˆ์Œ

์Šคํ”„๋ง MVC ์›น ์š”์ฒญ ์ฒ˜๋ฆฌ๊ณผ์ •์„ ์„ค๋ช…ํ•˜์‹œ์˜ค

  1. ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์ด DispatcherServlet์— ์ „๋‹ฌ
  2. DispatcherServlet์€ HandlerMapping์„ ์‚ฌ์šฉํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ์ปจํŠธ๋กค๋Ÿฌ ๊ฐ์ฒด๋ฅผ ๊ตฌํ•จ
  3. DispatcherServlet์€ ์ปจํŠธ๋กค๋Ÿฌ ๊ฐ์ฒด์˜ handleRequest() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์„ ์ฒ˜๋ฆฌ
  4. ์ปจํŠธ๋กค๋Ÿฌ์˜ handlerRequest() ๋ฉ”์„œ๋“œ๋Š” ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ ์ •๋ณด๋ฅผ ๋‹ด์€ ModelAndView ๊ฐ์ฒด๋ฅผ ๋ฆฌํ„ด
  5. DispatcherServlet์€ ViewResolver๋กœ๋ถ€ํ„ฐ ์‘๋‹ต ๊ฒฐ๊ณผ๋ฅผ ์ƒ์„ฑํ•  ๋ทฐ ๊ฐ์ฒด๋ฅผ ๊ตฌํ•จ
  6. ๋ทฐ๋Š” ํด๋ผ์ด์–ธํŠธ์— ์ „์†กํ•  ์‘๋‹ต์„ ์ƒ์„ฑ

@EnableWebMvc ๋Š” ์–ด๋””์— ํ•„์š”ํ•œ์ง€ ์„ค๋ช…ํ•˜์‹œ์˜ค

Spring MVC์—์„œ ํ•„์š”ํ•œ ๋นˆ๋“ค์„ ๋“ฑ๋กํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

@EnableWebMvc๋Š” ์–ด๋…ธํ…Œ์ด์…˜ ๊ธฐ๋ฐ˜์˜ Spring MVC๋ฅผ ๊ตฌ์„ฑํ•  ๋•Œ ํ•„์š”ํ•œ Bean ์„ค์ •๋“ค์„ ์ž๋™์œผ๋กœ ํ•ด์ฃผ๋Š” ์–ด๋…ธํ…Œ์ด์…˜์ž…๋‹ˆ๋‹ค.

๋˜ํ•œ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋“ฑ๋กํ•ด์ฃผ๋Š” Bean๋“ค ์ด์™ธ์— ์ถ”๊ฐ€์ ์œผ๋กœ ๊ฐœ๋ฐœ์ž๊ฐ€ ํ•„์š”๋กœ ํ•˜๋Š” Bean๋“ค์„ ๋“ฑ๋ก์„ ์†์‰ฝ๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค.

Infra/์šด์˜

heap dump๋ฅผ ํŠœ๋‹ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ด๋ณด์„ธ์š”.

๋ ˆ๋””์Šค ์บ์‹œ๋ฅผ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•ด์•ผํ•˜๋‚˜?

SSL ํ•ธ๋“œ์‰์ดํ‚น ๊ณผ์ •์€?

  1. SSL ํด๋ผ์ด์–ธํŠธ ์ปดํ“จํ„ฐ๊ฐ€ ์ž์‹ ์˜ ๋ฒ„์ „, ์•”ํ˜ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ชฉ๋ก, ๊ทธ๋ฆฌ๊ณ  ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์••์ถ• ๋ฐฉ์‹์„ "client hello" ๋ฉ”์‹œ์ง€์— ๋‹ด์•„ ์„œ๋ฒ„๋กœ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

  2. SSL ์„œ๋ฒ„๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ œ๊ณตํ•œ ๋ชฉ๋ก์—์„œ ์„œ๋ฒ„๊ฐ€ ์„ ํƒํ•œ ์•”ํ˜ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜, ์„ ํƒํ•œ ์••์ถ• ๋ฐฉ์‹๊ณผ ์„ธ์…˜ ID ๋ฐ CA(Certificate Authority)๊ฐ€ ์‚ฌ์ธํ•œ ์„œ๋ฒ„์˜ ๊ณต๊ฐœ ์ธ์ฆ์„œ๋ฅผ "server hello" ๋ฉ”์‹œ์ง€์— ๋‹ด์•„ ์‘๋‹ตํ•ฉ๋‹ˆ๋‹ค. ์ด ์ธ์ฆ์„œ๋Š” ๋Œ€์นญํ‚ค๊ฐ€ ์ƒ์„ฑ๋˜๊ธฐ ์ „๊นŒ์ง€ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋‚˜๋จธ์ง€ handshake ๊ณผ์ •์„ ์•”ํ˜ธํ™”ํ•˜๋Š” ๋ฐ์— ์“ธ ๊ณต๊ฐœํ‚ค๋ฅผ ๋‹ด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

  3. SSL ํด๋ผ์ด์–ธํŠธ๋Š” ์„œ๋ฒ„์˜ ๋””์ง€ํ„ธ ์ธ์ฆ์„œ๊ฐ€ ์œ ํšจํ•œ์ง€ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” CA ๋ชฉ๋ก์„ ํ†ตํ•ด ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

  4. ๋งŒ์•ฝ CA๋ฅผ ํ†ตํ•ด ์‹ ๋ขฐ์„ฑ์ด ํ™•๋ณด๋˜๋ฉด ํด๋ผ์ด์–ธํŠธ๋Š” ์˜์‚ฌ ๋‚œ์ˆ˜(pseudo-random) ๋ฐ”์ดํŠธ๋ฅผ ์ƒ์„ฑํ•ด ์„œ๋ฒ„์˜ ๊ณต๊ฐœํ‚ค๋กœ ์•”ํ˜ธํ™”ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋‚œ์ˆ˜ ๋ฐ”์ดํŠธ๋Š” ๋Œ€์นญํ‚ค๋ฅผ ์ •ํ•˜๋Š” ๋ฐ์— ์‚ฌ์šฉ๋˜๋ฉฐ ์ด ๋Œ€์นญํ‚ค๋Š” ๋‚˜์ค‘์— ๋ฉ”์‹œ์ง€ ๋ฐ์ดํ„ฐ๋ฅผ ์•”ํ˜ธํ™”ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

  5. SSL ์„œ๋ฒ„๊ฐ€ "ํด๋ผ์ด์–ธํŠธ ์ธ์ฆ์„œ ์š”์ฒญ"์„ ๋ณด๋‚ธ ๊ฒฝ์šฐ ํด๋ผ์ด์–ธํŠธ๋Š” ํด๋ผ์ด์–ธํŠธ์˜ ๋””์ง€ํ„ธ ์ธ์ฆ์„œ ๋˜๋Š” "๋””์ง€ํ„ธ ์ธ์ฆ์„œ ์—†์Œ ๊ฒฝ๊ณ " ์™€ ํ•จ๊ป˜ ํด๋ผ์ด์–ธํŠธ์˜ ๊ฐœ์ธ ํ‚ค๋กœ ์•”ํ˜ธํ™” ๋œ ์ž„์˜์˜ ๋ฐ”์ดํŠธ ๋ฌธ์ž์—ด์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ์ด ๊ฒฝ๊ณ ๋Š” ๊ฒฝ๊ณ ์ผ ๋ฟ์ด์ง€๋งŒ ์ผ๋ถ€ ๊ตฌํ˜„์—์„œ ํด๋ผ์ด์–ธํŠธ ์ธ์ฆ์ด ํ•„์ˆ˜์ผ ๊ฒฝ์šฐ handshake ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.

  6. ์„œ๋ฒ„๋Š” ํด๋ผ์ด์–ธํŠธ์˜ ์ธ์ฆ์„œ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋‚œ์ˆ˜ ๋ฐ”์ดํŠธ๋ฅผ ์ž๊ธฐ ๊ฐœ์ธํ‚ค๋กœ ๋ณตํ˜ธํ™”ํ•ด ๋Œ€์นญ ๋งˆ์Šคํ„ฐํ‚ค ์ƒ์„ฑ์— ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค.

  7. ํด๋ผ์ด์–ธํŠธ๋Š” handshake์˜ ํด๋ผ์ด์–ธํŠธ ๋ถ€๋ถ„์ด ์™„๋ฃŒ๋˜์—ˆ์Œ์„ ์•Œ๋ฆฌ๋Š” Finished ๋ฉ”์‹œ์ง€๋ฅผ ์„œ๋ฒ„์— ๋ณด๋‚ด๋ฉด์„œ ์ง€๊ธˆ๊นŒ์ง€์˜ ๊ตํ™˜ ๋‚ด์—ญ์„ ํ•ด์‹œํ•œ ๊ฐ’์„ ๋Œ€์นญํ‚ค๋กœ ์•”ํ˜ธํ™”ํ•˜์—ฌ ๋‹ด์Šต๋‹ˆ๋‹ค.

  8. ์„œ๋ฒ„๋Š” ์Šค์Šค๋กœ๋„ ํ•ด์‹œ๋ฅผ ์ƒ์„ฑํ•ด ํด๋ผ์ด์–ธํŠธ์—์„œ ๋„์ฐฉํ•œ ๊ฐ’๊ณผ ์ผ์น˜ํ•˜๋Š”์ง€ ๋ด…๋‹ˆ๋‹ค. ์ผ์น˜ํ•˜๋ฉด ์„œ๋ฒ„๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋Œ€์นญํ‚ค๋ฅผ ํ†ตํ•ด ์•”ํ˜ธํ™”ํ•œ Finished ๋ฉ”์‹œ์ง€๋ฅผ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

  9. ์ดํ›„๋ถ€ํ„ฐ SSL ์„ธ์…˜ ๋™์•ˆ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ๋Š” ๋Œ€์นญํ‚ค๋กœ ์•”ํ˜ธํ™”๋œ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜(HTTP) ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ  ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

โš ๏ธ **GitHub.com Fallback** โš ๏ธ