HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
🍗
[New] 조규현팀
/
🏪
TS Store
/
🎃
jvm 1부 [메모리, callByValue]
🎃

jvm 1부 [메모리, callByValue]

Person
완료율%
상태
완료
나의 블로그
https://bylog.notion.site/jvm-memory-new-Team-4ffe91d05878465d8a2242dc573afc0d
Think Sharing (TS)
🎃
jvm 1부 [메모리, callByValue]
주제목차내용
 

주제

자바 메모리 영역, 자바는 Call By Value일까, Call By Reference 일까?

목차

  • 전반적인 자바의 메모리 할당 및 실행 과정
  • 각 메모리 영역 역할
  • call by value 메모리 할당 그림까지 꼭 그리기 [Java] Java는 Call by reference가 없다

내용

  • 전반적인 자바의 메모리 할당 및 실행 과정
  • 각 메모리 영역 역할
    • background

    • 메모리
      • 프로그램을 실행하기 위한 데이터 및 명령어를 저장하는 공간
      • 😒메모리구조를 공부하는 이유
        • 같은 기능의 프로그램이더라도 메모리 관리에 따라 성능이 좌우됨.
        • 메모리 관리가 되지 않은 경우 속도저하 현상이나 튕김 현상 등이 일어날 수 있음
        • 한정된 메모리를 효율적으로 사용하여 최고의 성능을 내기 위함.

      jvm 메모리 정리

    • JVM은 Java Virtual Machine의 약자로, 자바 가상 머신이라고 불리운다.
    • 자바와 운영체제 사이에서 중개자 역할을 수행하며, 자바가 운영체제에 구애 받지 않고 프로그램을 실행할 수 있도록 도와줌(Write Once Run AnyWay)
    • 가비지 컬렉터를 사용한 메모리 관리도 자동으로 수행하며, 다른 하드웨어와 다르게 레지스터 기반이 아닌 스택 기반으로 동작함.
    • 전반적인 실행단계

      notion image
      compiler

      컴파일러(javac.exe)는 무엇을 하는가?

      1. 사용자가 생성한 클래스 코드의 문법을 체크한다.
      1. 사용자가 생성한 클래스 코드에 컴파일러가 추가적으로 필요한 코드와 새로운 문법 코드를 삽입한다.
          • java.lang package의 import 기능 등 사용된 클래스들의 전체 패키지 경로를 식별
          • 상속이 없으면 object 기본 상속
          • 생성자가 없으면 기본생성자 삽입
          • 모든 메서드(생성자포함)에 첫번째 매개변수 this 추가
          • interface 라면 메소드에 public abstract 처리
          • Java 최신 버전의 문법 코드로 변경
      1. 기본적인 최적화 작업을 수행
      1. bytecode로 변환
      1. 자바 컴파일러에 의해 자바 소스 파일은 바이트 코드로 변환됩니다.
      1. 이러한 바이트 코드를 JVM에서 읽어 들인 다음에, 우리가 자세히 다룰 예정인 과정들을 거쳐서 어떤 운영체제든간에 프로그램을 실행할 수 있도록 만든다.
      예를 들어 자바 소스 파일은 리눅스에서 만들었고 윈도우에서 이 파일을 실행하고 싶다면, 윈도우용 JVM만을 설치한다면 어떤 곳이든 우리가 작성한 프로그램이 동작할 수 있는 특징을 가지고 있다. (Every AnyWhere)
      • 한편으로는 JVM은 운영체제에 종속적이라는 특징을 알 수 있음.
      다른 프로그램과의 실행 구조 차이
      notion image
       

      jvm 내부 구조

      notion image
      상세하게 보기
      notion image
       
      전체 흐름 재정리
      프로그램이 실행되면, JVM은 OS으로부터 이 프로그램이 필요로 하는 메모리를 할당받고, JVM은 이 메모리를 용도에 따라 여러 영역으로 나누어 관리.
      • JVM은 크게 3부분으로 나눌 수 있다.
      • 클래스 파일을 로딩한 뒤 검증하고 초기화하는 Class loader subSystem, 클래스 파일을 저장하는 Runtime DataArea( 5가지 영역으로 나누어진다) , 클래스 파일(바이트코드)를 플랫폼에 맞는 기계어로 변환시켜 실행하는 Execution engine 이다.
      전반적인 구조 설명
      1. Class Loader
          • JVM 내로 클래스 파일을 로드하고, 링크를 통해 배치하는 작업을 수행하는 모듈입니다. 런타임 시에 동적으로 클래스를 로드함.
          • Runtime 시 동적으로 클래스를 로드(적재)한다.
          • jar 파일 내 저장된 클래스들을 jvm위에 탑재하고 사용하지 않는 클래스들은 메모리에서 삭제함. (동적 로딩)
            • 동적로딩 종류
              • 로드 타임 동적 로딩 : 하나의 클래스를 로딩하는 과정에서 필요한 다른 클래스를 동적으로 로딩하는 것
              • 런타임 동적 로딩 : 코드를 실행하는 순간에 필요한 클래스를 로딩하는 것
          • 자바는 컴파일 타임이 아니라 런타임에 참조한다!!!
            • 즉 클래스를 처음으로 참조할 때, 해당 클래스를 로드하고 링크한다.
            • 해당 역할을 로드가 수행한다.
      1. Execution Engine
          • 클래스 로더를 통해 JVM 내의 Runtime Data Area에 배치된 바이트 코드들을 명렁어 단위로 읽어서 실행.
          번외
          • 최초 JVM이 나왔을 당시에는 인터프리터 방식이었기때문에 속도가 느리다는 단점이 있었지만 JIT 컴파일러 방식을 통해 이 점을 보완하였습니다.
          • JIT는 바이트 코드를 어셈블러 같은 네이티브 코드로 바꿈으로써 실행이 빠르지만 역시 변환하는데 비용이 발생하였습니다.
          • 이 같은 이유로 JVM은 모든 코드를 JIT 컴파일러 방식으로 실행하지 않고, 인터프리터 방식을 사용하다가 일정한 기준이 넘어가면 JIT 컴파일러 방식으로 실행합니다.
      1. Garbage Collector
          • Garbage Collector(GC)는 힙 메모리 영역에 생성된 객체들 중에서 참조되지 않은 객체들을 탐색 후 제거하는 역할을 함
          • 이때, GC가 역할을 하는 시간은 언제인지 정확히 알 수 없습니다.
      1. Runtime Data Area
          • JVM의 메모리 영역으로 자바 애플리케이션을 실행할 때 사용되는 데이터들을 적재하는 영역.
          해당 영역은 크게 Method Area, Heap Area, Stack Area, PC Register, Native Method Stack로 나눌 수 있습니다.
          (1) Method area
          notion image
          상세 화면
          notion image
           
          • 모든 쓰레드가 공유하는 메모리 영역
            • 메소드 영역은 클래스, 인터페이스, 메소드, 필드, Static 변수 등의 바이트 코드를 보관.
          • 클래스 정보를 처음 메모리 공간에 올리 떄 초기화되는 대상을 저장하기 위한 메모리 공간
            • 올라가는 메소드의 바이트 코드는 프로그램의 흐름을 구성하는 바이트 코드들이 적재되어 있다.(main 메소드의 호출에서부터 계속된 메소드의 호출로 흐름을 이어가기 때문)
          • 대부분의 인스턴스의 생성도 메소드 내에서 명령하고 호출(생성자도 메소드임)
          • 전반적으로 대부분이 메소드 바이트 코드들로 이루어져 있기 때문에 거의 모든 바이트코드가 올라간다고 봐도 무방하다
          • Runtime Constant Pool이라는 별도의 관리 영영도 함께 존재하며 이는 상수 자료형을 저장하고 참조하여 중복을 막아 불필요한 메모리 생성을 피할 수 있게 됨.
          (2). Heap area
          notion image
          • 모든 쓰레드가 공유하며, new 키워드로 생성된 객체와 배열이 생성되는 영역입니다. 또한, 메소드 영역에 로드된 클래스만 생성이 가능하고 Garbage Collector가 참조되지 않는 메모리를 확인하고 제거하는 영역.
          구조 한눈에 파악하기
          • Permanent Generation- 생성된 객체들의 정보의 주소 값이 저장된 공간
          • New Area- Eden : 객체들이 최초로 생성되는 공간- Survivor : Eden에서 참조되는 객체들이 저장되는 공간
          • Old Area : New Area에서 일정시간이상 참조되고 있는 객체들이 저장되는 공간
          (3). Stack area
          • 메서드 호출 시마다 각각의 스택 프레임(그 메서드만을 위한 공간)이 생성함.
          •  메서드 안에서 사용되는 값들을 저장하고, 호출된 메서드의 매개변수, 지역변수, 리턴 값 및 연산 시 일어나는 값들을 임시로 저장한다. 그리고, 메서드 수행이 끝나면 프레임별로 삭제.
          (4). PC Register
          • 쓰레드가 시작될 때 생성되며, 생성될 때마다 생성되는 공간으로 쓰레드마다 하나씩 존재.
          • 쓰레드가 어떤 부분을 무슨 명령으로 실행해야할 지에 대한 기록을 하는 부분으로 현재 수행중인 JVM 명령의 주소를 갖는다.
          (5). Native method stack
          • 자바 외 언어로 작성된 네이티브 코드를 위한 메모리 영역.

          한눈으로 보기

          notion image
           
           
           
          jvm의 객체 소멸 대상 찾기 원리
          #가비지컬렉션(Garbage Collection) / JVM 구동원리에 이어서
          가비지 컬렉션, GC( Garbage Collection) 새로 생성된 대부분의 객체(Instance)는 Eden 영역에 위치한다. Eden영역에서 GC가 한 번 발생한 후 살아남은 객체는 Survivor 영역 중 하나로 이동된다. 이 과정을 반복하다가 계속해서 살아남아 있는 객체는 일정시간 참조되고 있다는 뜻이므로 Old영역으로 이동시킨다. Old영역에 있는 모든 객체들을 검사하여 참조되지 않은 객체들을 한꺼번에 삭제한다.
          #가비지컬렉션(Garbage Collection) / JVM 구동원리에 이어서
          https://asfirstalways.tistory.com/159
          #가비지컬렉션(Garbage Collection) / JVM 구동원리에 이어서
           
           
           
           
           

      왜 jvm이 필요할까?

      • 모든 C/C++ 바이너리(JVM뿐만 아니라)는 CPU에서 직접 실행됩니다. 일단 실행되면 이러한 프로그램은 운영 체제에서 제공하는 더 많은 기계어 코드를 호출하여 파일 읽기, 스레드 시작 또는 네트워크 사용과 같은 유용한 작업을 수행할 수 있습니다.
      • JVM은 Java 프로그램을 CPU에서 실행되는 명령으로 변환합니다. 그러나 배후에서 Java의 스레드, 파일 I/O 및 네트워크 소켓(몇 가지만 들자면)에는 모두 스레드/파일 등에 대해 운영 체제에서 제공하는 코드를 호출하는 명령이 포함되어 있습니다. 이것이 여전히 OS가 필요한 이유 중 하나입니다. JVM은 JIT 컴파일러에서 얻을 수 없는 기능을 제공합니다. 하루가 끝나면 JVM은 많은 기계 코드를 실행하지만 모든 기계 코드가 JIT(또는 인터프리터)에서 나오는 것은 아닙니다. 예를 들어 그 기계어 코드 중 일부는 가비지 수집을 수행합니다. 이것이 JVM이 필요한 이유입니다.
      • JVM은 Java 프로그램을 CPU에서 실행되는 명령으로 변환합니다. 그러나 배후에서 Java의 스레드, 파일 I/O 및 네트워크 소켓(몇 가지만 들자면)에는 모두 스레드/파일 등에 대해 운영 체제에서 제공하는 코드를 호출하는 명령이 포함되어 있습니다. 이것이 여전히 OS가 필요한 이유 중 하나입니다. JVM은 JIT 컴파일러에서 얻을 수 없는 기능을 제공합니다. 하루가 끝나면 JVM은 많은 기계 코드를 실행하지만 모든 기계 코드가 JIT(또는 인터프리터)에서 나오는 것은 아닙니다. 예를 들어 그 기계어 코드 중 일부는 가비지 수집을 수행합니다. 이것이 JVM이 필요한 이유입니다.
  • call by value 메모리 할당 그림까지 꼭 그리기 [Java] Java는 Call by reference가 없다
    • call by value vs vall by reference

      call by value

    • 전달받은 값을 복사하여 처리.
    • 즉 전달받은 값은 변경하여도 원본은 변경되지 않는다(무조건x)
      • value일 때(변경 x)
      • object일 때(변경 x)
      • value in object(변경 가능)

      call by reference:

    • 전달받은 값을 직접 참조.
    • 즉 전달받은 값을 변경할 경우 원본도 같이 변경.
    • public class A { public int value; public A(int i) { this.value = i; } }` `public class Test2 { public static void main(String[] args) { A a1 = new A(1); A a2 = new A(2); run(a1, a2); System.out.println(a1.value); // 111 System.out.println(a2.value); // 2 } static void run(A arg1, A arg2){ arg1.value = 111; arg2 = arg1; } }
       
      주소 값을 복사해서 넘기기 때문에 이는 call by value입니다. 복사된 주소 값으로 참조가 가능하니 주소 값이 가리키는 객체의 내용 변경된다.
       
      [Java] Java는 Call by reference가 없다
      프로그래밍을 하다 보면 꼭 알고 넘어가야 하는 개념이 있습니다. 바로 Call By Value, Reference입니다. 어떤 언어를 공부하든 나오는 개념이기도 합니다. Call by value 란, 값을 호출하는 것을 의미합니다. 전달받은 값을 복사하여 처리합니다. 즉 전달받은 값을 변경하여도 원본은 변경되지 않습니다. Call by reference 란 참조에 의한 호출을 의미합니다. 전달받은 값을 직접 참조합니다.
      [Java] Java는 Call by reference가 없다
      https://deveric.tistory.com/92
      [Java] Java는 Call by reference가 없다
      🚀 Visualizing memory management in JVM(Java, Kotlin, Scala, Groovy, Clojure)
      In this multi-part series, I aim to demystify the concepts behind memory management and take a deeper look at memory management in some of the modern programming languages. I hope the series would give you some insights into what is happening under the hood of these languages in terms of memory management.
      🚀 Visualizing memory management in JVM(Java, Kotlin, Scala, Groovy, Clojure)
      https://deepu.tech/memory-management-in-jvm/
      🚀 Visualizing memory management in JVM(Java, Kotlin, Scala, Groovy, Clojure)