gugbab2's GitBook
  • Language
    • C++
      • 강의
        • C++ 언매니지드 프로그래밍
          • C++ 프로그래밍
          • 출력(Output)
          • 입력(Input)
          • bool 타입, Reference
          • 상수(const)
          • 문자열(string)
          • 파일 입출력
          • 개체지향 프로그래밍1
          • 개체지향 프로그래밍2
          • 개체지향 프로그래밍3
          • 캐스팅(형변환, casting)
          • 인라인 함수
          • static 키워드
          • 예외(Exception)
          • STL(Standard Template Library) 컨테이너(Container) - Vector
          • STL 컨테이너 - Map
          • STL 컨테이너 - Queue, Stack, Set, List
          • 템플릿(Template) 프로그래밍
          • 새로운 키워드(C++11 ~) 1
          • 새로운 키워드(C++11 ~) 2
          • 새로운 자료형
          • 새로운 STL 컨테이너
          • 스마트(smart) 포인터
          • 이동생성자 및 이동대입연산자
          • constexpr
          • Lamda Expression
      • 책
        • The C++ Programming Lanuaage
          • 2부 : 기본 기능
            • 6. 타입과 선언
            • 7. 포인터, 배열, 참조
            • 8. 구조체(struct), 공용체(union), 열거형(enum)
            • 10. 표현식
            • 11. 선택 연산
            • 12. 함수
            • 13. 예외 처리
            • 15. 소스 파일과 프로그램
          • 3부 : 추상화 메커니즘
            • 16. 클래스
            • 17. 생성, 소멸, 복사와 이동
            • 18. 연산자 오버로딩
            • 19. 특수 연산자
            • 20. 파생클래스
        • 씹어먹는 C++
          • 2. C++ 참조자(reference) 의 도입
          • 5.1 연산자 오버로딩(비교, 대입 연산자)
          • 5-2. 연산자 오버로딩(이항, 입출력, 타입변환, 증감 연산자)
          • 6-2. 가상(virtual) 함수와 다형성
          • 6-3. 가상 함수에 대한 지식들
          • 9-1. 코드를 찍어내는 틀 - C++ 템플릿(template)
          • 9-2. 가변 길이 템플릿(Variadic template)
          • 9-3. 템플릿 메타 프로그래밍 (Template Meta Programming)
          • 9-4. 템플릿 메타 프로그래밍2
          • 16.1 유니폼 초기화(Uniform Initialization)
          • 토막글 2. 람다(lambda)
    • Java
      • 강의
        • 김영한의 실전 자바 - 기본편
          • 절차 지향 vs 객체 지향
            • 절차 지향 프로그래밍
            • 객체 지향 프로그래밍
          • 변수
            • 클래스 변수 / 인스턴스 변수, 멤버 변수 / 지역 변수
            • 기본형 vs 참조형
          • 패키지
            • 패키지
            • CLI 환경에서 .java 파일 컴파일 && 실행
          • 접근 제어자
            • 접근 제어자 - 기본
            • 캡슐화
          • static
            • 자바 메모리 구조
            • static 기본
            • 스택 영역, 힙 영역
              • 스택 영역, 힙 영역 - 기본
              • 메소드가 실행될 때 어떤일이 일어나는가?
          • 상속
            • 상속 기본
          • 다형성(Pilymorphism)
            • 다형성 기본
            • 다형성의 활용
              • 다형성의 활용 - 기본
              • 다형성의 활용 - 추상클래스
              • 다형성의 활용 - 인터페이스
            • 다형성과 설계
              • 좋은 객체 지향 프로그래밍
        • 김영한의 실전 자바 - 중급1편
          • 1. Object 클래스
          • 2. 불변 객체
          • 3. String 클래스
          • 4. 래퍼, Class 클래스
          • 5. 열거형 - ENUM
          • 6. 날짜와 시간
          • 7. 중첩 클래스, 내부 클래스1
          • 8. 중첩 클래스, 내부 클래스2
          • 9. 예외 처리1 - 이론
          • 10. 예외 처리 - 실습
        • 김영한의 실전 자바 - 중급2편
          • 1. 제네릭 - Generic1
          • 2. 제네릭 - Generic2
          • 3. 컬렉션 프레임워크 - ArrayList
          • 4. 컬렉션 프레임워크 - LinkedList
          • 5. 컬렉션 프레임워크 - List
          • 6. 컬렉션 프레임워크 - 해시(Hash)
          • 7. 컬렉션 프레임워크 - HashSet
          • 8. 컬렉션 프레임워크 - Set
            • 레드 블랙 트리
          • 9. 컬렉션 프레임워크 - Map, Stack, Queue
            • 왜(?) Set 은 내부에서 Map 을 사용할까?
          • 10. 컬렉션 프레임워크 - 순회, 정렬, 전체 정리
        • 김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성
          • 프로세스와 스레드 소개
          • 스레드 생성과 실행
          • 스레드 제어와 생명 주기1
          • 스레드 제어와 생명 주기2
          • 메모리 가시성
          • 동기화 - synchronized
            • synchronized 키워드 이해도 체크
          • 고급 동기화 - concurrent.Lock
          • 생산자 소비자 문제1
          • 생산자 소비자 문제2
          • CAS - 동기화와 원자적 연산
          • 동시성 컬렉션
          • 스레드 풀과 Executor 프레임워크1
          • 스레드 풀과 Executor 프레임워크2
        • 김영한의 실전 자바 - 고급 2편, I/O, 네트워크, 리플렉션
          • 문자 인코딩
          • I/O 기본1
          • I/O 기본2
          • I/O 활용
          • File, Files
          • 네트워크 - 프로그램1
          • 네트워크 - 프로그램2
          • 채팅 프로그램
          • HTTP 서버 만들기
          • 리플렉션
          • 애노테이션
          • HTTP 서버 활용
        • 김영한의 실전 자바 - 고급3편, 람다, 스트림, 함형 프로그래밍
          • 람다가 필요한 이유
          • 람다
          • 함수형 인터페이스
          • 람다 활용
          • 람다 vs 익명 클래스
          • 메서드 참조
          • 스트림API1 - 기본
          • 스트림 API2 - 기능
          • 스트림 API3 - 컬렉터
          • Optional
          • 디폴트 메서드
          • 병렬 스트림
          • 함수형 프로그래밍
        • 기초 탄탄! 독하게 시작하는 Java - Part2: OOP 와 JVM
          • 2. 클래스 - 첫 번째
          • 3. 클래스 - 두번째
          • 4. 상속과 관계
          • 6. JVM(Java Virtual machine) 기본 이론
          • 7. JVM 과 GC 그리고 객체
          • 8. 불변 객체와 String 클래스
      • 책
        • 자바의 신
          • 변수
            • 클래스 변수(static) 사용 주의 케이스
            • Java volatile 과 Atomic 변수(+CAS)
          • 연산자
            • 비트 연산자 활용 예제
          • 배열
          • 참조 자료형
          • 상속
          • Object 클래스
          • interface, abstract class, enum
          • 예외
          • String 클래스
            • String 구조
            • String 문자열을 byte 로 변환하기
            • String 클래스에서 자주 사용되는 메서드
            • String 클래스로 살펴보는 불변(Immutable)객체
            • StringBuilder, StringBuffer
          • Nested 클래스
          • 어노테이션
            • 어노테이션 기본
            • 어노테이션의 사용
          • JVM 이해하기
            • 왜 JVM 을 사용해?
            • JVM, JRE, JDK
            • JVM 구조 이해하기
            • 클래스 로더 시스템
            • JIT(Just-In-Time) 컴파일러
            • GC(Garbage Collector)
              • GC Part.1
              • GC Part.2
              • GC 튜닝
          • java.lang
            • Wrapper 클래스
            • System 클래스
          • Generic
            • 제네릭 기본
            • 와일드카드
            • 와일드카드 GET / SET 경계
            • 와일드카드 extends / super 사용시기
            • 혼동할 수 있는 와일드카드 표현
          • Collection
            • 자료구조
              • 이진 탐색 트리 vs 레드 블랙 트리
            • Collection
            • List
              • ArrayList
              • Vector
              • Stack
              • LinkedList
            • Set, Queue
              • HashSet
              • LinkedHashSet
              • TreeSet
              • Priority Queue
              • ArrayDeque
            • Map
              • HashMap
              • Hashtable
              • LinkedHashMap
              • TreeMap
          • Thread
            • Thread 기본
            • Thread 와 관련이 많은, Synchronized
            • Thread 를 통제하는 메서드
            • ThreadGroup
          • I/O
            • InputStream, OutputStream
            • Reader, Writer
          • Serializable, NIO
            • Serializable
            • NIO (New IO)
          • 네트워크 프로그래밍
            • 네트워크 기본 & TCP 통신
            • UDP 통신
          • 람다
            • 함수형 인터페이스
            • 람다란?
        • 벨둥(Bealdung)
          • Java Concurrency
            • Java Concurrency Basics
              • Overview of the java.util.concurrent
              • Guide to the Synchronized Keyword in Java
              • Guide to the Volatile Keyword in Java
              • Guide to the java.util.concurrent.Future
              • ThreadLocal in Java
      • 그 외
        • 시스템 콜과 자바에서의 시스템 콜 사용례
        • 자바 NIO 의 동작원리 및 IO 모델
        • 함수형 인터페이스(FunctionInterface) - 자바8
  • Spring
    • 강의
      • 스프링 핵심 원리 - 기본편
        • 큰 흐름 잡기
        • 스프링 핵심 원리 이해1 - 예제 만들기
        • 스프링 핵심 원리 이해2 - 객체 지향 원리 적용
        • 스프링 컨테이너와 스프링 빈
        • 싱글톤 컨테이너
        • 컴포넌트 스캔
        • 의존관계 자동 주입
        • 빈 생명주기 콜백
        • 빈 스코프
      • 토비의 스프링6 - 이해와 원리
        • 3. 오브젝트와 의존관계1
        • 3. 오브젝트와 의존관계2
        • 4. 테스트
        • 5. 템플릿
        • 6.예외
        • 7. 서비스 추상화
    • 책
      • JSP 2.3 웹 프로그래밍
        • Servlet
        • JSP
        • 쿠키 / 세션
        • MVC 패턴
        • 실무 때 고민할 만한 부분
      • 스프링 입문을 위한 자바 객체지향의 원리와 이해
        • 자바와 절차적/구조적 프로그래밍
        • 객체지향의 4대 특성
        • 객체지향 설계의 5원칙
        • 스프링이 사랑한 디자인 패턴
        • IoC / DI
        • AOP(Aspect Oriented Programming), 관점 지향 프로그래밍
      • 토비의 스프링 3.1
        • Spring vs Spring Boot
        • 1. 오브젝트와 의존관계
          • 1.4 제어의 역전(IoC)
          • 1.5 스프링의 IoC
          • 1.6 싱글톤 레지스트리와 오브젝트 스코프
    • 그 외
      • 스프링 부트(SpringBoot) 탄생 배경
  • CS
    • DATA STRUCTURES
      • 선택 정렬(Selection Sort)
      • 버블 정렬(Bubble Sort)
      • 삽입 정렬(Insertion Sort)
    • OS
      • 강의
      • 책
        • 혼자 공부하는 컴퓨터구조 + 운영체제
          • 1. 컴퓨터 구조 시작하기
          • 2. 데이터
          • 3. 명령어
          • 4. CPU 의 작동원리
          • 5. CPU 성능 향상 기법
          • 6. 메모리와 캐시메모리
          • 7. 보조기억장치
          • 8. 입출력장치
          • 9. 운영체제 시작하기
          • 10. 프로세스와 스레드
    • NETWORK
      • 그 외
        • REST API
          • REST API
          • URI & MIME type
          • Collection Pattern
          • Collection Pattern 적용
          • Spring Web MVC 구현
        • SSL 인증 동작
        • DTO & JSON & CROS
          • DTO
          • 직렬화(Serialization)
          • Jackson ObjectMapper
          • CROS
        • Connection Timeout / Read Timeout
      • 강의
        • 외워서 끝내는 네트워크 핵심이론 - 기초
          • Internet 기반 네트워크 입문
            • Host 는 이렇게 외우자
            • 스위치가 하는 일과 비용
          • L2 수준에서 외울 것들
            • NIC, L2 Frame, LAN 카드 그리고 MAC 주소
            • L2 스위치에 대해서
            • LAN 과 WAN 의 경계 그리고 Broadcast
          • L3 수준에서 외울 것들
            • IPv4 주소의 기본 구조
            • L3 IP Packet 으로 외워라
            • 패킷의 생성과 전달 및 계층별 데이터 단위
            • 이해하면 인생이 바뀌는 TCP/IP 송, 수신 구조
            • IP 헤더 형식
            • 서브넷 마스크와 CIDR
            • Broadcast IP 주소와 Localhost
            • TTL 과 단편화
            • 인터넷 설정 자동화를 위한 DHCP
            • ARP 과 Ping(RTT : Round Trip Time)
          • L4 수준 대표주자 TCP 와 UDP
            • TCP 와 UDP 개요
            • TCP 연결 및 상태 변화
            • TCP 연결 종료 및 상태 변화
            • TCP, UDP 헤더 형식과 게임서버 특징
            • TCP 가 연결이라는 착각
            • TCP 연결과 게임버그
          • 웹을 이루는 핵심기술
            • DNS
            • URL, URI
        • 외워서 끝내는 네트워크 핵심 이론 - 응용
          • 네트워크 장치의 구조
            • 세 가지 네트워크 장치 구조
            • Inline 구조
            • Out of path 구조와 DPI 그리고 망중립
            • Proxy(클라이언트 입장) - 우회
            • Proxy(클라이언트 입장) - 보호와 감시
            • Reverse Proxy(서버 입장)
          • 인터넷 공유기의 작동 원리
            • 공유기 개요
            • Symmetric NAT
            • Full Cone 방식
            • Restricted Cone, Port Restricted Cone
            • 포트 포워딩
            • UPnP 와 NAT
          • 부하분산 시스템 작동 원리
            • L4 부하분산 무정지 시스템
            • 대규모 부하분산을 위한 GSLB
          • VPN과 네트워크 보안 솔루션
            • PN 과 VPN
            • IPSec VPN 과 터널링 개념
            • VPN 과 재택근무
        • 외워서 끝내는 SSL 과 최소한의 암호기술
          • 기초이론
            • Checksum (검사합)
            • Hash
          • 암호기술에 대한 이해
            • 대칭키
            • 비대칭키
          • PKI 시스템과 인터넷
            • 인터넷을 위한 비대칭키 체계
            • 공개키 신뢰를 위한 검증체계
            • 웹서비스와 공인인증서
      • 책
        • 그림으로 배우는 네트워크 원리
          • 1. 네트워크 기본
          • 2. 네트워크를 만드는 것
          • 3. 네트워크의 공통 언어 TCP/IP
    • SECURITY
      • 그 외
        • Basic Auth
        • HMAC 기반 인증
    • 그 외
      • 동기/비동기 & 블로킹/논블록킹
  • DB
    • 그 외
      • 인덱스(Index)
      • 트랜잭션(TRANSACTION)
      • 실무에서 외래키를 사용하지 않는 이유
      • ORM vs SQL Mapper
      • 문자열 vs DATE
      • EXPLAIN 명령어
    • 강의
      • Real MySQL 시즌 1
        • Part.1
          • 1강. CHAR vs VARCHAR
          • 2강. VARCHAR vs TEXT
          • 3강. COUNT(*) & COUNT(DISTINCT) 튜닝
          • 4강. 페이징 쿼리 작성
          • 5강. Stored Function
      • 토크온 41차. JPA 프로그래밍 기본 다지기
        • 1. JPA 소개
        • 2. JPA 기초와 매핑
        • 3. 필드와 컬럼 매핑
        • 4. 연관관계 매핑
        • 5. 양방향 매핑
        • 6. JPA 내부구조
        • 7. JPA 객체지향쿼리
        • 8. Spring Data JPA 와 QueryDSL 이해
    • 책
  • Software Development Methodology
    • TDD
      • 강의
        • Spring Boot TDD - 입문부터 실전까지 정확하게
          • 세션2. TDD 소개
          • 세션5. API 설계
          • 세션6. TDD 주기 첫 번째 경험
          • 세션7. TDD 주기 반복
      • 그 외
        • 단위 테스트(Unit Test) 작성의 필요성
        • JUnit5
          • A Guide to JUnit 5
          • Guide to JUnit 5 Parameterized Tests
          • AssertJ Exception Assertions
          • Testing in Spring Boot
          • Junit 과 Mockito 기반의 Spring 단위 테스트 코드 작성법
        • Code Coverage
          • Code Coverage?
    • DDD
      • 책
        • 도메인 주도 설계(Domain-Driven Design)
          • 04 - 도메인의 격리
          • 05 - 소프트웨어에서 표현되는 모델
          • 06 - 도메인 객체의 생명주기
          • 07 - 언어의 사용(확장 예제) (1)
          • 07 - 언어의 사용(확장 예제) (2)
        • 도메인 주도 개발 시작하기
          • 1. 도메인 모델 시작하기
          • 2. 아키텍처 개요
          • 3. 애그리거트
          • 4. 리포지터리와 모델 구현
            • DAO vs Repository
      • 강의
        • DDD 세레나데(NEXTSTEP)
          • 1주차
            • 도메인 주도 설계 등장 배경
            • 레거시 코드
            • 유연한 설계 - ASSERTION
          • 2주차
            • 전략적 설계 - UBIQUITOUS LANGUAGE
            • 전략적 설계 - BOUNDED CONTEXT
          • 3주차
            • 전술적 설계 - VALUE OBJECT 와 ENTITY
            • 전술적 설계 - AGGREGATE 와 REPOSITORY
            • 전술적 설계 - SERVICE
    • REFACTORING
      • 일급 컬렉션(First Class Collection) 소개와 사용해야하는 이유
  • ARCHITECTURE
    • Event Driven Architecture
  • 멘토링
    • F-Lab
      • 10회차(2024.12.29)
Powered by GitBook
On this page
  • 1. Java 와 C++ 메모리 관리 차이
  • Native 언어 (C,C++ ... )
  • JVM 언어
  • Java 와 C++ 메모리 관리 차이
  • 2. JVM 구성요소 정리
  • Class loader
  • Runtime data area
  • Execution engine
  • 3. .class 파일과 바이트 코드 소개
  • 4. 클래스 로더 및 로딩 과정
  • 클래스 로더 종류
  • 로딩(Loading)
  • 링킹(Linking)
  • 초기화(Initialization)
  • 5. 런타임 데이터 영역
  • 공통 단위
  • 쓰레드 단위
  • 6. JVM 스택 구조
  • Stack area
  • Stack frame 구조
  • 7. JVM 힙 영역 GC
  • Heap 영역
  • JVM Garbage collector
  • GC 기술의 시작
  • JVM Heap 영역
  1. Language
  2. Java
  3. 강의
  4. 기초 탄탄! 독하게 시작하는 Java - Part2: OOP 와 JVM

6. JVM(Java Virtual machine) 기본 이론

1. Java 와 C++ 메모리 관리 차이

Native 언어 (C,C++ ... )

Native 언어는 컴파일 후, CPU 가 이해할 수 있는 기계어로 직접 번역되고 이후 실행된다. (때문에, 운영체제 환경에 대해서 직접적인 의존성을 가진다)

윈도우에서 개발된 C, C++ 코드를 리눅스, 유닉스 환경에서 실행시킬 수 없다. 각 운영체제 별로 기계어가 다르기 때문이다. (같은 코드라도 각 운영체제에 맞는 기계어로 번역해주어야 실행이 가능하다)

결론적으로, Native 언어는 운영체제에 직접적으로 요청을 할 수 있기 떄문에, 하드웨어와 직접적으로 연관되어 있다.

JVM 언어

하드웨어를 소프트웨어로 구현한 것을 Virtual Machine 이라고 부르며, 이 Virtual Machine 에서 인식할 수 있는 코드가 Java Byte Code 일 때, JVM(Java Virtual Machine) 이라고 부른다.

결과적으로 JVM 은 소프트웨어로 CPU + 가상메모리(RAM + SSD) 모두가 구현된 것을 의미한다. 여기에 운영체제가 제공하는 기능 일부도 제공한다.

때문에, JVM 을 이해한다는 것은 OS, 컴퓨터구조를 모두 이해한다는 의미와 같다.. (열라 어렵겠지?)

결론적으로, JVM 언어는 소프트웨어와 직접적으로 연관되어 있다.

Java 와 C++ 메모리 관리 차이

JVM 은 User Mode Application 으로 Application Process 범위를 넘어서지 않는다. 쉽게 말해서 JVM 프로세스가 다운된다고 해서 OS 가 다운될 일은 없다! (물론 JNI 를 통해서 운영체제에 영향을 줄 수 있다. 해당 케이스는 패스~~)

때문에, 보안적 장점이 명확하다! (Native 언어는 운영체제와 직접적인 의존성을 가지기 때문에, 사소한 문제라도 OS 가 다운될 수 있다)

C++

  • 객체에 대한 모든 관리 책임은 개발자에게 있음 (메모리 할당 및 해제)

  • 객체의 생명주기에 개발자가 개입하는 구조

Java

  • 개체 메모리 해제는 전적으로 JVM 의 몫

  • 하지만, 문제 발생시 구조를 알아야 대응 가능

2. JVM 구성요소 정리

Class loader

소프트웨어의 시점은 크게 3가지로 나뉘어 진다.

  • 컴파일

  • 링킹 : 실행에 필요한 라이브러리, 시동코드 등을 컴파일 된 코드에 연결해주는 과정

  • 실행

하지만, JVM 은 컴파일, 실행(링킹 + 실행) 과정으로만 나뉘어진다.

클래스 로더는 여기서 컴파일 된 바이트코드를 로딩하고, 링킹하고, 초기화하는 역할을 담당한다. (매우 중요한 역할이다!)

  • 로딩(Loading) : 바이트코드를 JVM 내 Runtime data area(Method area) 에 배치하는 작업.

  • 링킹(Linking) : 로드 된 클래스 파일들을 사용 가능한 상태로 변경한다.

  • 초기화(initialization) : 정적(static) 초기화 블록이나 정적(static) 변수들을 초기화하는 과정을 의미하고, 클래스가 사용될 때 최초로 한번만 동작한다.

클래스 로딩은 JVM 이 올라올 때 한번에 로딩되는 것이 아니라, 해당 코드가 호출 될 때마다 동적으로 로딩된다. 때문에 앞선 클래스 로딩의 절차적으로 문제가 생긴다면 다음 클래스 로딩에 문제가 생길 수 밖에 없다.

Runtime data area

  • Method area : 클래스 관련 정보(클래스 메서드, 클래스 정보 등), 문자열 상수를 관리하는 영역

  • Heap area : GC 가 관리하는 영역

  • Stack area : 스레드마다 가지고 있는 영역

  • PC register : 스레드마다 가지고 있는 영역

  • Native method stack

Execution engine

  • Interpreter : 기본적으로 바이트코드를 기계어로 번역해서 실행한다.

  • JIT compiler : 반복되는 바이트코드들은 미리 기계어로 번역해놓고 실행시킨다.

  • Garbage collector : 힙 메모리를 관리해준다.

3. .class 파일과 바이트 코드 소개

...

4. 클래스 로더 및 로딩 과정

.class 파일은(Java byte code) JVM 내에서 실제로 실행 가능한 코드이다.

클래스 로더 종류

  • 이름을 알고 있는 특정 클래스에 대한 정의(Java Byte code) 를 가져오는 역할을 수행

    • 가져온다는 것을 보았을 때, 네트워크를 통해서 .class 파일을 가져올 수도 있다. (그만큼 확장성이 있다는 뜻?!)

  • 클래스 로더의 종류는 다음과 같다.

    • Bootstrap ClassLoader

    • Platform ClassLoader

    • Application ClassLoader

  • 3가지 클래스 로더에서 클래스를 로드하지 못했을 때, ClassNotFoundException 이 발생한다.

부트스트랩 클래스 로더

  • JVM 이 실행될 때 가장 먼저 실행되는 클래스로더이다.

  • JVM 에서 핵심 라이브러리(rt.jar, tools.jar 내에는 java.lang.*, java.util.* 등 핵심 클래스가 있다) 로 취급되는 코드들을 로드한다.

  • 이 로더는 Java 로 작성된 것이 아니라, Native 코드로 작성되어 있다.

부트스트랩?

  • 부트스트랩이라는 용어는 아무것도 없는 상태에서 스스로 부팅하는 과정을 의미한다.

  • 즉, 시스템의 기초적인 기능을 초기화하고 운영체제를 실행할 수 있도록하는 과정을 의미한다.

플랫폼 클래스 로더

  • Java9 부터 도입되었으며 부트스트랩 클래스로더와 애플리케이션 클래스로더의 경계선을 명확하게 하기 위해서 존재하는 클래스로더이다.

  • JVM 핵심 라이브러리 외에 확장 라이브러리들을 로드한다. (Java SE, Java EE API 플랫폼 내 라이브러리..)

애플리케이션 클래스 로더

  • JVM에서 사용자가 작성한 클래스 + 외부 라이브러리를 로드한다.

  • 가장 최상위에 위치한다.

로딩(Loading)

💡 Java 클래스 로딩 후 사용 과정

JVM에서 .class 파일이 메모리에 올라간 후 사용되는 과정은 크게 아래와 같은 단계를 따른다.

  1. Loading → .class 파일을 찾아 메모리(Runtime data area 내 Method area) 에 올림 이 시점에 java.lang.class 객체가 생성된다!

    1. Bootstrap

    2. Platform

    3. Application

  2. Linking

    1. Verification → 바이트코드 유효성 검사

    2. Preparation → static 필드 기본값(0, null) 할당

    3. Resolution → 심볼(이름)을 실제 참조로 해석 (필요 시점까지 지연 가능)

  3. Initialization → static 블록 실행, 상수 할당 등

  4. Using

  5. Unloading → GC에 의해 클래스 언로드 (드물게 발생)

✅ 클래스 로더는 실행 중에도 유연한 구조를 가능하게 해준다.

Java는 클래스 로더를 통해 클래스의 로딩, 링킹, 초기화를 런타임 시점에 동적으로 수행할 수 있다.

이 덕분에 실행 성능에 초기 비용이 들 수 있지만 (클래스 로더에 너무 많은 기능이 있다),

대신 다음과 같은 유연성과 확장성을 얻는다.

장점1. 🔁 인터페이스만 맞으면, 런타임에 구현 클래스를 교체할 수 있다.

MyService service = (MyService) Class.forName("com.kyungho.MyServiceImpl")
                                     .getDeclaredConstructor()
                                     .newInstance();
  • 리플렉션을 통해 런타임에 클래스 이름만 바꿔도 구현체를 변경할 수 있음

  • DI 컨테이너(Spring)나 플러그인 시스템의 핵심 기반

장점2. 🌐 코드를 네트워크나 외부 경로에서 로딩할 수 있다.

URL url = new URL("https://kyungho.dev/plugin.jar");
URLClassLoader loader = new URLClassLoader(new URL[]{url});
Class<?> pluginClass = loader.loadClass("com.kyungho.Plugin");
Object plugin = pluginClass.getDeclaredConstructor().newInstance();
  • 실행 중에 .jar 파일을 네트워크에서 다운받아 로딩할 수 있음

  • IDE 플러그인, 게임 모드, 빌드 없이 기능 확장 등 다양한 상황에서 활용됨

장점3. ⏱ 해석(Resolution) 은 필요할 때까지 지연된다.

  • 해석은 클래스 링크(Linking) 과정 중 일부이지만,

  • 호출될 때까지 지연될 수 있음 (invokevirtual, invokedynamic 등)

  • 이는 다형성과 동적 바인딩을 지원하기 위해 필요한 구조

링킹(Linking)

✅ 1. Verification (검증)

📦 개념

  • JVM은 .class 파일이 문법적으로 올바른지, 구조적으로 안전한지를 확인합니다.

  • 이는 악성 .class 파일이나 잘못된 바이트코드 실행을 막기 위한 "보안 장치" 입니다.

🛠 왜 보안 장치인가?

  • .class 파일은 사람이 작성한 것이 아니라 컴파일 된 이진 코드입니다. 누군가 바이트코드를 조작하면, 정상적인 Java 코드에서는 할 수 없는 위험한 행동이 가능해질 수 있습니다.

  • 예를 들어, 스택을 넘치게 하거나 타입을 속이거나, 존재하지 않는 메서드를 호출하는 식의 공격이 가능하다.

  • JVM은 이런 비정상적인 바이트코드를 검증(Verification) 단계에서 미리 탐지하고 차단합니다.

  • JVM 언어는 Native 언어처럼 운영체제에 직접 영향을 줄 수는 없지만, 애플리케이션 내부 데이터를 망가뜨리거나 실행 흐름을 왜곡하는 행위는 막아야 합니다. (JNI 를 사용해서 직접적으로 운영체제에 요청을 날릴수도 있지만 해당 케이스는 제외)

🛠 주요 검사항목

  • .class 파일 포맷 및 구조 검증

  • 상속 구조, 메서드 시그니처, 접근 제한자 등의 유효성 확인

  • 바이트코드 명령어의 타입 안정성, 스택 정합성, 제어 흐름 안전성 검사

  • 참조하는 클래스가 존재하는지 여부 확인

✅ 2단계. Preparation (준비)

📦 개념 설명

  • 클래스가 인스턴스화되기 전, static 필드들에 대해 메모리 공간을 할당하고 기본값으로 초기화하는 단계이다.

    • 정수형: 0, 참조형: null, boolean: false 등.

    • 단, 이 메모리는 힙이 아니라 메서드 영역(Method Area) 또는 HotSpot 기준 Metaspace에 할당된다.

🛠 주요 특징

  • 클래스는 아직 초기화되지 않았고, <clinit>() 메서드도 실행되지 않았다.

  • 이 시점에 존재하는 건 java.lang.Class 객체뿐이며, 이는 메타정보 용도로만 존재한다. → 리플렉션, 어노테이션 처리 등에 사용됨.

  • static final 상수는 컴파일 시점에 값이 확정된 리터럴 상수인 경우에만 이 시점에 초기화된다. -> 초기화 할수도 안할수도 있다. (예: static final int A = 42; → OK, static final int B = SomeCalc(); → 초기화 단계까지 대기)

✅ 3단계. Resolution (해석)

📦 개념 설명

  • .class 파일 내부에는 클래스, 필드, 메서드 등의 참조 정보가 문자열 혹은 인덱스(=심볼) 형태로 저장되어 있다.

  • 하지만 JVM이 이 정보를 직접 사용할 수는 없기 때문에, 실제 메모리상의 참조로 변환하는 과정이 필요하다. 이 과정을 해석(Resolution) 이라고 한다.

    즉, 해석은 심볼(이름 정보) → 실제 메모리 주소(클래스/메서드/필드 참조)로 매핑하는 작업이다.

  • 이때 변환된 참조는 Metaspace에 올라가 있는 클래스 구조체 등을 통해, 실제 JVM이 사용할 수 있게 된다.

🛠 주요 특징

  • 이 작업은 실행 시점까지 지연될 수 있으며,

  • 특히 invokevirtual, invokedynamic 같은 바이트코드 명령어와 함께 호출 시점에 수행됩니다.

  • 이는 Java의 다형성(오버라이딩, 인터페이스 구현 등)을 구현하기 위해 반드시 필요한 구조입니다.

초기화(Initialization)

✅ 초기화는 언제 발생하는가?

  • 링킹(Linking)이 끝났다고 해서 자동으로 초기화되지 않습니다.

  • 초기화는 반드시 “클래스의 명시적 사용” 이 발생해야만 수행됩니다.

트리거 조건
예시

static 필드 읽기

MyClass.value

static 메서드 호출

MyClass.run()

클래스 인스턴스 생성

new MyClass()

Class.forName() 호출

Class.forName("MyClass") → 무조건 초기화 발생

서브클래스 초기화 시 부모 클래스도 초기화

new ChildClass() 시 부모도 초기화됨

✅ 초기화 단계에서 수행되는 작업

순서
내용
예시

①

static 필드에 명시된 값 할당

static int x = 42;

②

static 블록 실행

static { System.out.println("Init!"); }

내부적으로는

위 과정을 <clinit>이라는 특수 메서드에서 실행

JVM이 자동 호출

5. 런타임 데이터 영역

공통 단위

Method area

  • JVM이 클래스를 로딩할 때, 클래스의 구조 정보(타입, 필드, 메서드, 정적 변수 등)를 저장하는 영역

  • Java 7까지는 PermGen(Permanent Generation) 영역을 통해 구현

  • Java 8부터는 PermGen이 제거되고, Metaspace라는 새로운 구조로 대체됨

PermGen vs Metaspace

PermGen

  • Java 7까지 사용

  • JVM 내 별도의 영역

  • 크기가 고정되어 있었고, 설정을 초과할 경우 OutOfMemoryError: PermGen space 발생

  • 클래스 수가 많아지면 관리에 한계

Metaspace

  • Java 8부터 도입

  • JVM 외부, 네이티브 메모리(Native Memory) 에 존재 (네이티브 메모리 : 운영체제가 관리하는 메모리)

  • 크기가 동적으로 조절 가능

  • 시스템 자원이 허용하는 한 무제한에 가깝게 클래스 정보를 저장할 수 있음

⚙️ Runtime Constant Pool (RCP) 정리

Runtime Constant Pool 이란?

  • .class 파일은 Constant Pool Table을 포함하고 있으며, 클래스의 필드, 메서드, 상수 등의 심볼릭 정보(예: "클래스 이름", "메서드 이름", 문자열 리터럴 등)를 저장함

  • JVM이 클래스를 로딩하면 이 테이블을 바탕으로 Runtime Constant Pool (RCP) 을 생성함

  • RCP는 클래스마다 하나씩 존재하며, 바이트코드 실행을 위한 핵심 참조 테이블 역할을 수행함

Runtime Constant Pool의 역할

  • 숫자, 문자열, 심볼릭 참조(클래스 이름, 메서드 서명 등)를 포함

  • 심볼릭 참조는 실행 시점에 실제 메모리 주소로 해석됨 (이 과정을 Resolution이라고 함)

  • 정적 필드 접근, 메서드 호출, 상수 사용 등에 쓰이는 참조 기반 데이터

☑️ Java 버전별 RCP 저장 위치

Java 7 이하

  • RCP는 PermGen(Method Area)에 저장됨

  • PermGen은 JVM 내부 메모리이며, 크기가 고정되어 있음

  • GC 대상이기도 하고, 너무 많은 클래스를 로딩하면 OutOfMemoryError: PermGen space가 발생할 수 있음

Java 8 이상

  • RCP는 Metaspace에 저장됨

  • Metaspace는 JVM 외부 네이티브 메모리이며, 운영체제가 직접 관리함

  • 크기를 동적으로 조정할 수 있으며, PermGen처럼 고정된 한계가 없음

  • 시스템 메모리가 허용하는 범위 내에서 확장 가능함

☑️ Intern Pool과의 차이

Runtime Constant Pool

  • 모든 .class 파일에서 유래된 상수 정보를 저장

  • 바이트코드 해석, 메서드 호출, 상수 값 참조 등에 사용됨

  • 클래스 로딩 시 고정 생성됨 → 실행 중 수정되지 않음

  • 위치는 Java 8 이상에서 Metaspace

Intern Pool

  • String 객체만을 저장하는 별도의 문자열 상수 풀

  • 동일한 문자열을 공유하고 중복 생성을 피하기 위해 사용됨

  • 실행 중에 String.intern()을 통해 새로운 문자열을 추가할 수 있음

  • 위치는 Java 7까지는 PermGen, Java 8 이상에서는 Java Heap 영역

  • GC의 대상이 됨

Heap area

  • JVM 프로세스가 사용할 수 있는 데이터 영역의 대부분을 차지한다.

    • 물론 사용하기에는 큰 힙 메모리 영역이 좋을 수 있다.

    • 하지만 그만큼 GC 를 해야하는 범위가 넓어진다는 의미이기 때문에, 성능이 느려질 수 있다.

  • 우리가 인스턴스라고 불리는 것들은 힙 메모리에 저장된다.

  • JVM 옵션을 통해서 사용하는 힙 메모리 범위를 제한할 수 있다.

쓰레드 단위

Stack area

  • 스택 영역은 일반적으로 사용할 수 있는 공간이 정해져있다.

  • 재귀함수를 잘못 호출하거나, 반복문을 잘못 사용하는 경우 StackOverFlow 가 발생한다.

PC(Program counter) register

  • 각 스레드의 명령어의 위치를 나타내는 포인터를 저장하는 영역

Native method stack

  • Native Method Stack은 JVM이 Java 코드 외에 C/C++ 등으로 작성된 네이티브 메서드를 호출할 때 사용하는 스택 영역입니다.

  • JNI, OS 레벨 API 연동 시 활용되며, 일반적인 Java 스택과는 별도로 관리됩니다.

6. JVM 스택 구조

Stack area

  • JVM Stack은 각 쓰레드별로 할당되며, 메서드 호출마다 Stack Frame이 생성된다.

  • 각 Stack Frame은 메서드 실행에 필요한 정보들을 포함한다:

    • 지역 변수 테이블: 인자, 로컬 변수 저장. int, 참조형은 슬롯 1개, long, double은 2개 슬롯 사용

    • 피연산자 스택: 바이트코드 연산 중간값 저장. JVM은 스택 기반 구조이므로 레지스터 대신 이걸 사용

    • 동적 링크 영역: 심볼릭 참조를 실제 메서드/필드로 연결해 캐싱함

    • 반환 주소: 호출한 메서드로 돌아갈 PC 값

  • this 참조는 항상 0번 슬롯에 저장 (인스턴스 메서드에 한함)

  • Stack은 슬롯 수 기준으로 크기를 제한할 수 있으며, 초과 시 StackOverflowError 발생

Stack frame 구조

7. JVM 힙 영역 GC

Heap 영역

  • GC(Garbage collector) 가 관리하는 메모리 영역으로 Java 에서 사용되는 객체의 인스턴스 및 배열이 저장되는 공간

  • 설정에 따라 크기를 변경하거나 고정할 수 있음

    • 부족 시, OutOfMemoryError 오류 발생

    • 힙 메모리를 늘리면 그만큼 GC 범위가 넓어지는 것을 의미하기 때문에,

    • OutOfMemoryError 가 발생하더라도 힙 메모리를 늘리는 것은 신중하게 고민해야 한다.

  • 세대별 컬렉션 이론(Generational collection theory) 을 기반을 설계 및 운영

    • Eden, Survivor

    • New / Old generation

    • 영구 세대(Metaspace)

JVM Garbage collector

  • Heap 영역에서 참조되지 않는 개체를 수집 및 제거해 메모리 회수

    • 참조되지 않는 개체라는 것은, 스택 영역 내 참조 변수가 사용되지 않는 상황을 의미한다.

    • 정적 변수에 객체를 생성하게 되면, 프로그램 종료까지 메모리를 회수할 수 없다. (GC 불가)

  • Minor / Major(Full) GC

    • GC 수행 시 프로그램 일시 정지 (stop-the-world)

  • GC 속도

    • Minor GC 가 보통 1초 이내 완료

    • Full GC 는 보통 수 초 이상 진행되기도 하며 이 지연 때문에, DB 연결이 끊기는 등 운영문제가 발생할 수 있다.

      • 때문에, Full GC 가 일어나지 않도록 하는게 포인트겠지?!

GC 기술의 시작

  • Java 에서(거의) 모든 인스턴스는 힙 영역에 저장

  • GC 기술은 1960년대 만들어진 기술 -> 리스프 언어 창시자 존 맥카시

  • GC 가 처리해야 할 문제의 핵심 요소

    • 회수 대상 메모리를 판단하는 것

    • 메모리 회수 시점

    • (구체적인) 메모리 회수 방법

JVM Heap 영역

Previous4. 상속과 관계Next7. JVM 과 GC 그리고 객체

Last updated 18 days ago