느리더라도 꾸준히

[JVM]변수 선언과 할당시 관점으로 JVM 동작 이해하기 본문

Java

[JVM]변수 선언과 할당시 관점으로 JVM 동작 이해하기

테디규 2022. 11. 4. 20:07

글의 목표

Person kyu = new Person("steadykyu", "950204-xxxxxx","Seoul");

위 코드대로 객체 생성 시, 각각의 데이터들이 Java 메모리의 어느 부분에 저장되는지 이해한다.


Person 클래스 설명

class Person {
    String name; // 유저 닉네임이라고 해보자.
    PersonInfo personalInfo;
    public Person(String name, String socialNumber, String address) {
        this.name = name;
        personalInfo = new PersonInfo(socialNumber, address);
    }

    // 회원 가입 메서드
    void save(){
        // name과 personalInfo 를 이용하여 회원가입 로직 실행했다고 가정
        System.out.println("회원가입 완료");
        System.out.println("이름 : "+ name);
        System.out.println("주민번호 : "+ personalInfo.SocialNumber);
        System.out.println("주소 : "+ personalInfo.ADDRESS);
    }

    public class PersonInfo{
        private String name;
        // 주민번호
        private final String SocialNumber;
        private final String ADDRESS;

        private PersonInfo(String socialNumber, String address) {
            this.SocialNumber = socialNumber;
            this.ADDRESS = address;
        }

        public String getSocialNumber() {
            return SocialNumber;
        }

        public String getAddress() {
            return ADDRESS;
        }
    }

}
public class SignUp {
    public static void main(String[] args) {
        Person kyu = new Person("steadykyu", "950204-xxxxxx", "Seoul");
        kyu.save();
    }
}
  • Person 클래스는 필드(name - 닉네임), 메서드(save), 내부 클래스(PersonInfo - 개인정보)를 가지고 있다.
  • 매개변수 값을 입력받아, “kyu”라는 객체(인간)를 생성하고 있다.
  • PersonInfo는 외부에서 접근할수 없도록 코드를 작성해본것인데 글의 주제와는 상관 없으므로 넘어가도 된다.

Java 전체 메모리 영역

  1. 우리가 작성한 Person 소스 코드는 Person.java로 저장됩니다.
  2. Java 컴파일러(javac.exe)에 의해 Person.class로 변환됩니다.
  3. Class Loader를 통해 JVM Runtime Data Area로 로딩합니다.
  4. Runtime Data Area에 로딩 된 .class들은 Execution Engine을 통해 해석합니다.
    1. 해석된 바이트 코드는 Runtime Data Area의 각 영역에 배치됩니다.

전체적인 흐름만 이해하고, Runtime Data Area 에서 우리가 필요한 세 영역(Method Area, Heap Area, Stack Area) 만 쪼개서 봐봅시다.

메서드 영역, 스택영역, 힙 영역

이제 부터 아래 소스 코드를 하나하나 쪼개서 메모리에 어떻게 저장되는지 봅시다.

Person kyu = new Person("steadykyu", "950204-xxxxxx","Seoul")

클래스 - (Person)

클래스 ,구체적으로 클래스 코드는 Method 영역(=Class Area, static Area)에 저장됩니다.

그러므로 메서드 코드와 생성자 코드도 Method 영역에 저장됩니다.

  • 이 두 코드는 Method 영역에서 저장되고 공유됩니다.
  • 그러므로 우리는 객체를 생성할 때 마다 메서드와 생성자를 선언하지 않고, 공유된 코드를 호출해 올 수 있습니다.

또한 정적(static) 필드와 상수도 이 클래스 영역에 저장되어, 클래스를 통해 만들어지는 모든 인스턴스들에게 공유 될 수 있습니다.

참조변수 - (kyu)

kyu는 참조 변수로 생성된 객체의 주소 값을 저장하고 있습니다. 일반적으로 참조형 변수들은 주소값은 stack에 실제 값은 Heap 영역에 저장합니다. 그림에서 확인해보면, 객체와 배열이 Heap 영역에 저장된 모습을 볼 수 있습니다.

참고 : 메서드 호출시 생성되는 지역변수도 이 stack 영역에 저장됩니다.

객체 생성 - new Person(…)

new 명령어는 객체를 생성하고 해당 객체(아래 참고)를 Heap 영역에 넣어줍니다.

  • 타입과 상관없이 static이 붙지않은 인스턴스 변수들(필드)
  • inner class

Person(…) 는 생성자로, 매개변수의 값을 이용하여 객체를 초기화 해줍니다.

그러므로 생성자로 초기화한 객체를 new 명령어로 Heap 영역에 넣어준 후, kyu 참조변수에 주소값을 부여하고 이 주소값은 stack 영역에 저장 시킵니다.

이제 kyu 참조변수의 주소값(100)을 이용하여 Heap영역의 값을 꺼내 올 수 있게 됩니다.

  • ex) kyu.name

출처

https://coding-factory.tistory.com/828

https://coding-factory.tistory.com/830

Comments