[{"data":1,"prerenderedAt":483},["ShallowReactive",2],{"post-document:\u002Fjava\u002Fjvm\u002F2026\u002F08\u002F10\u002Fjvm-classloader-memory\u002F":3},{"id":4,"title":5,"body":6,"categories":463,"date":465,"description":466,"extension":467,"image":468,"key_concepts":468,"last_modified_at":468,"legacyPath":469,"meta":470,"navigation":405,"part":472,"path":473,"published":405,"robots":468,"seo":474,"series":475,"stem":476,"strengths":468,"summary":468,"tags":477,"tradeoffs":468,"__hash__":482},"posts\u002Fposts\u002FBackend\u002FJAVA\u002Fjvm\u002F2026-08-10-jvm-classloader-memory.md","Java 실행과 JVM Part 3: ClassLoader와 JVM 메모리",{"type":7,"value":8,"toc":450},"minimark",[9,13,18,29,36,75,92,98,102,105,115,119,125,128,134,137,146,149,153,159,164,168,174,177,186,189,195,198,204,224,227,231,237,240,259,262,268,271,275,283,289,292,295,298,313,316,322,325,329,332,338,341,347,350,353,356,361,365,368,381,386,421,424,427,433,437,440,446],[10,11,5],"h2",{"id":12},"java-실행과-jvm-part-3-classloader와-jvm-메모리",[14,15,17],"h3",{"id":16},"실행-과정-요약","실행 과정 요약",[19,20,26],"pre",{"className":21,"code":23,"language":24,"meta":25},[22],"language-text","Java Source (.java)\n    ↓\nJava Compiler (javac)\n    ↓\nByte Code (.class)\n    ↓\nClassLoader\n    ↓\nJVM\n    ↓\nOS\n    ↓\nHardware\n","text","",[27,28,23],"code",{"__ignoreMap":25},[30,31,33],"h4",{"id":32},"mainjava",[27,34,35],{},"Main.java",[19,37,41],{"className":38,"code":39,"language":40,"meta":25,"style":25},"language-java shiki shiki-themes github-light github-dark","public class Main {\n    public static void main(String[] args) {\n        System.out.println(\"Hello\");\n    }\n}\n","java",[27,42,43,51,57,63,69],{"__ignoreMap":25},[44,45,48],"span",{"class":46,"line":47},"line",1,[44,49,50],{},"public class Main {\n",[44,52,54],{"class":46,"line":53},2,[44,55,56],{},"    public static void main(String[] args) {\n",[44,58,60],{"class":46,"line":59},3,[44,61,62],{},"        System.out.println(\"Hello\");\n",[44,64,66],{"class":46,"line":65},4,[44,67,68],{},"    }\n",[44,70,72],{"class":46,"line":71},5,[44,73,74],{},"}\n",[19,76,80],{"className":77,"code":78,"language":79,"meta":25,"style":25},"language-bash shiki shiki-themes github-light github-dark","javac Main.java\n","bash",[27,81,82],{"__ignoreMap":25},[44,83,84,88],{"class":46,"line":47},[44,85,87],{"class":86},"sScJk","javac",[44,89,91],{"class":90},"sZZnC"," Main.java\n",[19,93,96],{"className":94,"code":95,"language":24,"meta":25},[22],"Main.java\n    ↓ javac\nMain.class\n",[27,97,95],{"__ignoreMap":25},[99,100,101],"p",{},"Main.class에는 CPU가 직접 실행하는 기계어가 아니라 JAVA Bytecode가 들어있다.",[99,103,104],{},"그 다음에는",[99,106,107,110,111,114],{},[27,108,109],{},"java Main","을 실행하면 ",[27,112,113],{},"Main.class","를 가져와 실행한다.",[14,116,118],{"id":117},"_1-classloader","1. ClassLoader",[19,120,123],{"className":121,"code":122,"language":24,"meta":25},[22],".class → ClassLoader → JVM\n",[27,124,122],{"__ignoreMap":25},[99,126,127],{},"ClassLoader의 역할은",[129,130,131],"blockquote",{},[99,132,133],{},"JVM이 실행에 필요한 .class 파일을 찾아서 JVM 메모리에 올리는 것.",[99,135,136],{},"예를 들어",[19,138,140],{"className":38,"code":139,"language":40,"meta":25,"style":25},"User user = new User();\n",[27,141,142],{"__ignoreMap":25},[44,143,144],{"class":46,"line":47},[44,145,139],{},[99,147,148],{},"JVM이 실행하면서 User 클래스가 필요하다.\n그러면 ClassLoader가 User.class를 찾아 로딩한다.",[14,150,152],{"id":151},"_2-jvm-메모리-영역","2. JVM 메모리 영역",[19,154,157],{"className":155,"code":156,"language":24,"meta":25},[22],"                JVM\n\n        ┌─────────────────┐\n        │    공유 영역      │\n        │                 │\n        │ Heap            │\n        │ Method Area     │\n        │ Code Cache      │\n        └─────────────────┘\n\n        ┌─────────────────┐\n        │  Thread별 영역    │\n        │                 │\n        │ Stack           │\n        │ PC Register     │\n        │ Native Stack    │\n        └─────────────────┘\n",[27,158,156],{"__ignoreMap":25},[129,160,161],{},[99,162,163],{},"모든 스레드가 같이 사용하는 메모리와 각 스레드가 자기 것만 사용하는 메모리가 있다.",[14,165,167],{"id":166},"_3-heap","3. Heap",[99,169,170,173],{},[27,171,172],{},"Heap","은 객체 인스턴스를 저장하는 영역이다.",[99,175,176],{},"이라고 적혀있지. 예를 들어",[19,178,180],{"className":38,"code":179,"language":40,"meta":25,"style":25},"User user = new User(\"민형\");\n",[27,181,182],{"__ignoreMap":25},[44,183,184],{"class":46,"line":47},[44,185,179],{},[99,187,188],{},"하면",[19,190,193],{"className":191,"code":192,"language":24,"meta":25},[22],"user ───────→ [User 객체]\n                name = \"민형\"\n",[27,194,192],{"__ignoreMap":25},[99,196,197],{},"실제는",[99,199,200,203],{},[44,201,202],{},"User 객체","가 주로 Heap에 생성된다.",[19,205,207],{"className":38,"code":206,"language":40,"meta":25,"style":25},"new User();\nnew Dog();\nnew Cat();\n",[27,208,209,214,219],{"__ignoreMap":25},[44,210,211],{"class":46,"line":47},[44,212,213],{},"new User();\n",[44,215,216],{"class":46,"line":53},[44,217,218],{},"new Dog();\n",[44,220,221],{"class":46,"line":59},[44,222,223],{},"new Cat();\n",[99,225,226],{},"으로 만들어지는 갹체들이 Heap과 연결된다.",[14,228,230],{"id":229},"_4-stack","4. Stack",[19,232,235],{"className":233,"code":234,"language":24,"meta":25},[22],"Thread 1 - Stack\nThread 2 - Stack\n",[27,236,234],{"__ignoreMap":25},[99,238,239],{},"stack은 메서드가 호출될 때 그 메서드를 실행하기 위한 작업 공간",[19,241,243],{"className":38,"code":242,"language":40,"meta":25,"style":25},"static void hello() {\n    int age = 20;\n}\n",[27,244,245,250,255],{"__ignoreMap":25},[44,246,247],{"class":46,"line":47},[44,248,249],{},"static void hello() {\n",[44,251,252],{"class":46,"line":53},[44,253,254],{},"    int age = 20;\n",[44,256,257],{"class":46,"line":59},[44,258,74],{},[99,260,261],{},"hello()가 호출되면 Stack에 메서드 실행을 위한 Stack Frame이 생성된다.",[19,263,266],{"className":264,"code":265,"language":24,"meta":25},[22],"Thread Stack\n\n┌────────────────────┐\n│ hello() Frame      │\n│                    │\n│ age = 20           │\n└────────────────────┘\n",[27,267,265],{"__ignoreMap":25},[99,269,270],{},"메서드가 끝나면 해당 Stack Frame도 제거",[14,272,274],{"id":273},"_5-heap과-stack-연결","5. Heap과 Stack 연결",[19,276,277],{"className":38,"code":179,"language":40,"meta":25,"style":25},[27,278,279],{"__ignoreMap":25},[44,280,281],{"class":46,"line":47},[44,282,179],{},[19,284,287],{"className":285,"code":286,"language":24,"meta":25},[22],"Stack                         Heap\n\nuser ─────────────────────→ [User 객체]\n                              name=\"민형\"\n",[27,288,286],{"__ignoreMap":25},[99,290,291],{},"user -> 참조 변수\nUser -> 실제 객체",[99,293,294],{},"이게 JVM 메모리까지 연결된다.",[99,296,297],{},"일반적인 지역 참조 변수 user는 해당 메서드 Stack Frame에서 관리된다.\nnew User()로 만들어진 실제 객체는 Heap에 존재한다.",[19,299,301],{"className":38,"code":300,"language":40,"meta":25,"style":25},"User a = new User(\"민형\");\nUser b = a;\n",[27,302,303,308],{"__ignoreMap":25},[44,304,305],{"class":46,"line":47},[44,306,307],{},"User a = new User(\"민형\");\n",[44,309,310],{"class":46,"line":53},[44,311,312],{},"User b = a;\n",[99,314,315],{},"개념적으로",[19,317,320],{"className":318,"code":319,"language":24,"meta":25},[22],"Stack                         Heap\n\na ─────────┐\n           ├──────────────→ [User 객체]\nb ─────────┘                 name=\"민형\"\n",[27,321,319],{"__ignoreMap":25},[99,323,324],{},"참조 변수가 두 개, Heap의 객체는 하나\n앞에서 공부한 참조 변수 개념이 JVM에서 이어진다.",[14,326,328],{"id":327},"_6-왜-stack이-thread마다-따로-있나","6. 왜 Stack이 Thread마다 따로 있나?",[99,330,331],{},"예를 들어 두 개의 thread가 동시에 실행된다고 해보자",[19,333,336],{"className":334,"code":335,"language":24,"meta":25},[22],"Thread 1 → calculate() 실행\nThread 2 → sendEmail() 실행\n",[27,337,335],{"__ignoreMap":25},[99,339,340],{},"각자 실행 중인 메서드와 지역 변수가 다르므로",[19,342,345],{"className":343,"code":344,"language":24,"meta":25},[22],"Thread 1 Stack\n\ncalculate()\nx = 10\ny = 20\n\nThread 2 Stack\n\nsendEmail()\nemail = \"...\"\n",[27,346,344],{"__ignoreMap":25},[99,348,349],{},"각 Thread가 자기 Stack을 가지고 있어야할 필요가 있다.",[99,351,352],{},"반면 Heap 객체는 여러 Thread가 함께 접근할 수 있다.",[99,354,355],{},"그래서 동시성 프로그램에서 같은 heap 객체에서",[99,357,358],{},[27,359,360],{},"여러 Thread → 같은 Heap 객체 수정 → Race Condition",[14,362,364],{"id":363},"_7-method-area","7. Method Area",[99,366,367],{},"Method Area",[369,370,371,375,378],"ul",{},[372,373,374],"li",{},"클래스 메타데이터",[372,376,377],{},"상수 풀",[372,379,380],{},"Runtime Constant Pool",[129,382,383],{},[99,384,385],{},"JVM이 클래스 자체에 대한 정보를 저장하는 공간",[19,387,389],{"className":38,"code":388,"language":40,"meta":25,"style":25},"class User {\n    String name;\n\n    void hello() {\n    }\n}\n",[27,390,391,396,401,407,412,416],{"__ignoreMap":25},[44,392,393],{"class":46,"line":47},[44,394,395],{},"class User {\n",[44,397,398],{"class":46,"line":53},[44,399,400],{},"    String name;\n",[44,402,403],{"class":46,"line":59},[44,404,406],{"emptyLinePlaceholder":405},true,"\n",[44,408,409],{"class":46,"line":65},[44,410,411],{},"    void hello() {\n",[44,413,414],{"class":46,"line":71},[44,415,68],{},[44,417,419],{"class":46,"line":418},6,[44,420,74],{},[99,422,423],{},"이 클래스 이름은 User다\n어떤 필드가 있다\n어떤 메서드가 있다\n상속 관계는 어떻다\n상수는 무엇이 있다",[99,425,426],{},"현대 Java에서 이런 클래스 메타데이터를 주로 Metaspace를 통해 구현",[19,428,431],{"className":429,"code":430,"language":24,"meta":25},[22],"Method Area → 개념적인 JVM 영역\nMetaspace   → HotSpot JVM에서 이를 구현하는 핵심 영역\n",[27,432,430],{"__ignoreMap":25},[14,434,436],{"id":435},"_8-code-cache","8. Code Cache",[99,438,439],{},"이미지에는",[99,441,442,445],{},[27,443,444],{},"Code Cache","에는 JIT 컴파일된 네이티브 코드가 저장된다.",[447,448,449],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}",{"title":25,"searchDepth":53,"depth":53,"links":451},[452],{"id":12,"depth":53,"text":5,"children":453},[454,455,456,457,458,459,460,461,462],{"id":16,"depth":59,"text":17},{"id":117,"depth":59,"text":118},{"id":151,"depth":59,"text":152},{"id":166,"depth":59,"text":167},{"id":229,"depth":59,"text":230},{"id":273,"depth":59,"text":274},{"id":327,"depth":59,"text":328},{"id":363,"depth":59,"text":364},{"id":435,"depth":59,"text":436},[40,464],"jvm","2026-08-10 10:20:00 +0900","Java 소스가 실행되는 과정과 ClassLoader, Heap, Stack, Method Area, Code Cache의 역할을 정리한다.","md",null,"\u002Fjava\u002Fjvm\u002F2026\u002F08\u002F10\u002Fjvm-classloader-memory\u002F",{"layout":471},"post","3","\u002Fposts\u002Fbackend\u002Fjava\u002Fjvm\u002F2026-08-10-jvm-classloader-memory",{"title":5,"description":466},"Java 실행과 JVM","posts\u002FBackend\u002FJAVA\u002Fjvm\u002F2026-08-10-jvm-classloader-memory",[478,479,480,172,481,367,444],"Java","JVM","ClassLoader","Stack","iwDFP8yxm0_u1ncXLoGb2X1AJYLXA_l1beJ39vsMPzU",1788744784849]