[자바 무료 강의] Java == Call By Value - 코드라떼
Lesson List button
코스자바로 배우는 프로그래밍
hamburger button
강의Java == Call By Value최종수정일 2021-11-10
아이콘약 8분

자바의 call by value에 대해서 배웁니다. 해당 강의를 잘 이해하기 위해서는 이전에 '자바 메모리 모델 - 기초' 강의를 들어야 합니다. 혹시나 듣지 않았다면 꼭 듣고 오세요.

추가 노트

이번 강의는 추가 노트로 정리하지 않습니다.
강의의 흐름으로 내용을 이해하셔야 하기 때문에 강의를 여러번 복습해서 듣는 것을 추천드립니다.

도전자 질문
아이콘glimmer(2022-01-12 20:27 작성됨)
답변 정말 감사합니다. 덕분에 잘 이해가 되었습니다. 
다만 3번 질문에서 제가 이해한 것이 맞는지.. 확인을 받고 싶습니다.

1. 힙 영역은 스레드들이 공유하기 때문에 값이 바뀌는 메서드 정보를 힙 영역에 넣을 필요성이 떨어진다.

2. 영상에 나온 Person 클래스 실행흐름을 해석(object 생성자 실행 이후 person 클래스 실행흐름으로 돌아왔을 때)할 때


- local variable array의 0번째 index에 있는 this(person 인스턴스 객체의 참조값)를 읽어 operand stack에 push한다.
- 메서드 영역의 runtime constant pool에 있는 상수 24를 가져와 operand stack에 push한다. --- 특히 이 부분
- this와 상수 24를 operand stack에서 pop하여 힙 영역 안에 있는 인스턴스 변수의 값을 저장한다.

이렇게 해석할 수 있을까요?
아이콘코드라떼(2022-01-12 22:39 작성됨)
안녕하세요 코드라떼입니다 :)

1. 힙 영역은 스레드들이 공유(O)하기 때문에 값이 바뀌는 메서드 정보를 힙 영역에 넣을 필요성이 떨어진다.(필요성이 떨어지는건 알 수 없음, 이전 질문의 답변은 이해를 돕기 위한 예시 설명입니다)

너무 어렵게 생각하지 마시고 단순하게 메서드 정보는 메서드 영역에 저장한다는 것만 아시면 될듯합니다.

2. 영상에 나온 Person 클래스 실행흐름을 해석(object 생성자 실행 이후 person 클래스 실행흐름으로 돌아왔을 때)할 때


- local variable array의 0번째 index에 있는 this(person 인스턴스 객체의 참조값)를 읽어 operand stack에 push한다. (O)
- 메서드 영역의 runtime constant pool에 있는 상수 24를 가져와 operand stack에 push한다. --- 특히 이 부분 
2byte로 표현 가능한 값(-32,768 ~ 32,767)은 직접 상수 값을 push합니다. 그 이상의 값은 constant pool의 상수값을 push합니다.
- this와 상수 24를 operand stack에서 pop하여 힙 영역 안에 있는 인스턴스 변수의 값을 저장한다. (O)

감사합니다.
아이콘glimmer(2022-01-12 01:44 작성됨)
안녕하세요, 강의 중 질문이 있어서 질문을 드립니다.

1. 2:40~50초 즈음에 ref1 참조값을 ‘pop’한 후 참조값을 복사하여 operand stack에 push한다고 나오는데요, 이 과정에서 operand stack에 ref1 참조값이 1개가 남아야 하지 않나요? 이후 강의를 계속 들어보면 person 인스턴스의 age1, age2 값을 채운 후 참조값을 operand stack에 push한다는 것을 보면 1개가 남는 것이 맞아 보여서 질문드립니다.

2. ‘Ref1 참조값을 pop하여 person 인스턴스의 생성자 메서드를 실행’한다는 부분이 잘 와닿지 않습니다. 그러면 힙 메모리에 person 인스턴스(인스턴스 변수 포함)를 저장한 후 operand에 ref1 참조값을 push했다가 다시 pop하며 person 인스턴스의 생성자 메서드를 실행한다는 뜻인가요? // 만약 이 말이 맞다면, 참조값을 operand stack에서 push, pop하는 과정을 거쳐 생성자 메서드를 실행한다는 것을 받아들이면 되는건가요? (그렇게 하는 이유가 있다면 알고 싶습니다. Ex. 초기화 과정이 이런 방식으로 일어난다?)

3. 영상에서의 Person 클래스가 이해가 잘 가지 않습니다. 제가 고민한 바로는 ‘영상에서의 person class가 사실은 public class person(24, 54)로 생성자를 위한 값이 들어가고, 밑에서 매개변수 2개(ex. int a, int b)를 갖는 생성자가 명시된 형태를 띈다.(ex. this.age1 = a, this.age2 = b)’라고 이해했는데 이게 맞는 것인가요?

4. Person 클래스에서 this가 local variable array에 들어가 있는건 내부적으로 처리가 되어 있는 것인가요? 내부 원리를 잘 모르겠습니다.

5. Swap 메서드의 person.age2 = person.age1 부분에서 ref1, 54, ref1, 24 이렇게 ref1 참조값이 2번 operand stack에 담겼다 pop되는 이유가 ‘person 인스턴스에 있는 age1(또는 age2) 값을 읽어내거나 수정하기 위해서는 person 인스턴스의 참조값이 필요하기 때문이다(접근하기 위해서)’라고 이해하면 될까요?

강의 감사드립니다.
아이콘코드라떼(2022-01-12 14:59 작성됨)
안녕하세요. 코드라떼입니다 :)

1. 2:40~50초 즈음에 ref1 참조값을 'pop'한 후 참조값을 복사하여 operand stack에 push한다고 나오는데요, 이 과정에서 operand stack에 ref1 참조값이 1개가 남아야 하지 않나요? 이후 강의를 계속 들어보면 person 인스턴스의 age1, age2 값을 채운 후 참조값을 operand stack에 push한다는 것을 보면 1개가 남는 것이 맞아 보여서 질문드립니다.

1) 2:40~50초 즈음에 ref1 참조값을 'pop'한 후 참조값을 복사하여 operand stack에 push한다고 나오는데요, 이 과정에서 operand stack에 ref1 참조값이 1개가 남아야 하지 않나요?

답변: 2:40~50초 즈음 참조값을 'pop'한 후 ref1 참조값을 복사하여 Person 인스턴스의 참조값 2개를 operand stack에 두 번 푸쉬합니다. 그래서 ref1이 operand stack에 두 개가 됩니다. 그 부분은 영상에서는 말로만 설명하고 복사하고 push한 결과만 보여주었습니다. 정확히 알고 계셔야 하는 부분은 Frame마다 operand stack이 '별도'로 존재합니다. 
메인 메서드와 연관된 Frame의 operand stack에 저장된 참조값 둘 중 하나는 인스턴스에 접근하여 생성자를 실행하기 위해 사용되며, 나머지 하나는 이후에 Person person; 변수에 참조값을 저장하기 위해 사용됩니다.

2) 이후 강의를 계속 들어보면 person 인스턴스의 age1, age2 값을 채운 후 참조값을 operand stack에 push한다는 것을 보면 1개가 남는 것이 맞아 보여서 질문드립니다.

답변: Person 인스턴스의 생성자 흐름과 연관된 Frame과 메인 메서드의 흐름과 연관된 Frame의 operand stack은 서로 다릅니다 :)

2. ‘Ref1 참조값을 pop하여 person 인스턴스의 생성자 메서드를 실행’한다는 부분이 잘 와닿지 않습니다. 그러면 힙 메모리에 person 인스턴스(인스턴스 변수 포함)를 저장한 후 operand에 ref1 참조값을 push했다가 다시 pop하며 person 인스턴스의 생성자 메서드를 실행한다는 뜻인가요? // 만약 이 말이 맞다면, 참조값을 operand stack에서 push, pop하는 과정을 거쳐 생성자 메서드를 실행한다는 것을 받아들이면 되는건가요? (그렇게 하는 이유가 있다면 알고 싶습니다. Ex. 초기화 과정이 이런 방식으로 일어난다?)

1) 힙 메모리에 person 인스턴스(인스턴스 변수 포함)를 저장한 후 operand에 ref1 참조값을 push했다가 다시 pop하며 person 인스턴스의 생성자 메서드를 실행한다는 뜻인가요?

답변: 맞습니다 :) 추가로 모든 클래스는 Object 클래스를 상속받으므로 상위 클래스인 Object와 연관된 생성자도 실행됩니다. 강의 내용에서는 이부분은 간단히만 설명하고 생략했습니다.

2) 만약 이 말이 맞다면, 참조값을 operand stack에서 push, pop하는 과정을 거쳐 생성자 메서드를 실행한다는 것을 받아들이면 되는건가요?

답변: 맞습니다 :) 초기화 과정이 이런 방식으로 실행됩니다. 

3. 영상에서의 Person 클래스가 이해가 잘 가지 않습니다. 제가 고민한 바로는 ‘영상에서의 person class가 사실은 public class person(24, 54)로 생성자를 위한 값이 들어가고, 밑에서 매개변수 2개(ex. int a, int b)를 갖는 생성자가 명시된 형태를 띈다.(ex. this.age1 = a, this.age2 = b)’라고 이해했는데 이게 맞는 것인가요?

잘못 이해하신 것 같습니다. 영상에선 생성자가 명시된 형태를 가지고 있지 않습니다.
자바 가상 머신 구현체마다 다르겠지만 인스턴스를 좀 더 쉽게 이해하기 위한 방법으로 이렇게 보시면 쉬울듯 합니다

Heap에 저장된 Person 인스턴스
참조값 #2915(예시)
--------------------------
| int age1 (Person) |
| int age2 (Person) |
--------------------------
Person 인스턴스는 메모리 공간에 위와 같이 적재 합니다. (메타 데이터 생략)
클래스의 생성자와 메서드 정보는 별도의 메모리 공간에 적재된다고 보시면 됩니다.
생성자의 로직과 메서드내에서 사용하는 정보는 어떤 인스턴스든 동일하므로 Heap에 저장하지 않습니다.
메서드나 생성자내에서 인스턴스마다 사용하는 참조값이 다르니 Heap에 같이 저장해야 하는게 아닌가 생각할 수 있지만 아닙니다.

만약에 이러한 코드가 있다고 가정해봅시다.

class Person {
    …
    public void setAge(int age) {
        this.age1 = age; 
    }
}

Person person1 = new Person();
Person person2 = new Person();

person1에 저장된 참조값 #2945
--------------------------
| int age1 (Person) |
| int age2 (Person) |
--------------------------
person2에 저장된 참조값 #2990
--------------------------
| int age1 (Person) |
| int age2 (Person) |
--------------------------

setAge 메서드 내에서 사용하는 age1 변수에 접근하기 위한 this는 인스턴스에 따라 서로 다를 수 있습니다.

class Person {
    …
    public void setAge(int age) {
        #2945.age1 = age; <— 이런거 아닙니다
    }
}
class Person {
    …
    public void setAge(int age) {
        #2990.age1 = age; <— 이런거 아닙니다
    }
}

그러나 착각할 수 있는 부분이 메서드내에서 접근하는 인스턴스 변수 정보가 다르므로 Heap에 메서드 정보를 별도로 저장해야 하는거 아닌가 생각할 수 있으나

class Person {
    …
    public void setAge(int age) {
        메서드가 실행되는 인스턴스의 참조값을 가져온다.age1 = age;
    }
}
this.age1에서 this 명령어의 의미가 'Frame내의 인스턴스의 참조값'이라고 한다면 this는 절댓값이 아니므로 굳이 메서드의 정보를 Heap에 저장할 필요가 없습니다.

설명이 어렵긴 한데 Heap에 저장되는 것은 인스턴스 변수와 메타 데이터가 저장된다고만 생각하시면 될듯합니다.

https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5.4
Method Area 해당 부분을 참고해보세요 :)


4. Person 클래스에서 this가 local variable array에 들어가 있는건 내부적으로 처리가 되어 있는 것인가요? 내부 원리를 잘 모르겠습니다.

this 적재 시점은 local variable array 초기화 시점으로 보시면 될 듯 합니다.(Stack Frame 적재 시)

5. Swap 메서드의 person.age2 = person.age1 부분에서 ref1, 54, ref1, 24 이렇게 ref1 참조값이 2번 operand stack에 담겼다 pop되는 이유가 ‘person 인스턴스에 있는 age1(또는 age2) 값을 읽어내거나 수정하기 위해서는 person 인스턴스의 참조값이 필요하기 때문이다(접근하기 위해서)’라고 이해하면 될까요?

맞습니다 :) 접근하기 위해서는 인스턴스의 참조값이 필요합니다.
아이콘bng4535(2022-01-01 23:23 작성됨)
1.
public static void main(String[] args){
....
} 
가 실행될 때, 영상에서 local variable array에서 args에 해당하는 메모리주소에 ref0이 들어가 있는데 이건 operand를 거치지 않고 처음부터 그냥 저장이 되는건가요? 어떤 원리로 저장이 되어있는건지 궁금해요

2. 그리구 생성자가 실행될 때 argument가 없는데 this포인터를 저장하는 메모리가 할당되어 있는 것도 왜 그런것인지 알고 싶어요

3. 객체의 변수에 접근할 때 객체를 가리키는 포인터를 이용하던데, 그 포인터를 통해 객체의 위치로 이동한다음 그 객체 내의 변수의 위치는 어떻게 아는건가요? 그림에 있는 거보다 더 많은 정보가 오고가는 건가요??
아이콘코드라떼(2022-01-02 13:46 작성됨)
안녕하세요. 코드라떼입니다 :)

1.
프로그램이 실행되면 항상 Main StackFrame에 String[] args 매개 변수가 할당되고, 전달되는 값이 있다면 Heap 메모리에 배열의 공간(heap)을 할당하여 저장됩니다.
에디터를 이용하거나 또는 프롬프트, 터미널로 자바 프로그램을 실행할 때 익숙하시면 다음과 같이 실험해 볼 수 있습니다.
만약에 자바 프로그램을 실행할 때 "code"와 "latte" 값을 전달하려면 아래와 같이 작성하면 됩니다.
> java Main "code" "latte"
만약에 이렇게 값이 전달되면 String[] args 매개변수에는 길이가 2이고 "code", "latte"값을 저장하는 배열이 할당됩니다.
만약에 값이 전달되지 않을 경우는 길이가 0입니다.

operand stack 부분과 관련하여 바이트코드 상으로는 operand stack의 연산 과정을 거쳐서 args 매개변수에 저장하는 부분은 작성되어 있지 않습니다.
자바 가상 머신이 프로그램 시작시 내부적으로 처리하는 것으로 보입니다.

2.
this 포인터는 argument와 상관없이 '자기 자신을 가리키는 포인터'입니다. 

예를들어 아래와 같은 코드가 있을 때
public class Person {
    public int age1 = 54;
    public int age2 = 24;
    
    public setAge1(int age) {
        age1 = age;
    }
}
Person 인스턴스가 메모리에 할당되면 참조값이 #41512라고 가정해봅시다.
동영상에서는 this 또는 ref로 표기했었는데요. 
StrackFrame이 Person 내에서 동작하는 경우 자기 자신을 가리키는 this(#41512)로 표기하고 외부에서 Test 인스턴스를 접근할 때는 ref(#41512)로 표기했습니다.

만약에 setAge1(..) 호출 시 age1 인스턴스 변수에 접근하려면 StackFrame 내에 Test 인스턴스에 접근할 수 있는 포인터가 필요합니다.
코드상으로는 age1이지만 사실 this.age1 또는 ref.age1이라고 보면 됩니다.
결론적으로 this 참조값을 통해 Person 인스턴스내에 있는 age1 변수에 접근합니다.

3.
객체 내의 변수의 위치는 바이트코드에서 드러나지 않으며 자바 가상 머신에 의해 내부적으로 처리됩니다.
그림에 있는 것은 바이트코드의 명령어 기준으로 동작 원리를 설명한 것이며, 구현 원리나 더 정확한 절차를 알기 위해서는 가상 머신 구현체를 봐야 합니다.

감사합니다 :)

이용약관|개인정보취급방침
알유티씨클래스|대표, 개인정보보호책임자 : 이병록
이메일 : cs@codelatte.io
사업자등록번호 : 824-06-01921
통신판매업신고 : 2021-성남분당C-0740
주소 : 경기도 성남시 분당구 대왕판교로645번길 12, 9층 24호
Lesson List button
코스자바로 배우는 프로그래밍
hamburger button
강의Java == Call By Value최종수정일 2021-11-10
아이콘약 8분

자바의 call by value에 대해서 배웁니다. 해당 강의를 잘 이해하기 위해서는 이전에 '자바 메모리 모델 - 기초' 강의를 들어야 합니다. 혹시나 듣지 않았다면 꼭 듣고 오세요.

추가 노트

이번 강의는 추가 노트로 정리하지 않습니다.
강의의 흐름으로 내용을 이해하셔야 하기 때문에 강의를 여러번 복습해서 듣는 것을 추천드립니다.

도전자 질문
아이콘glimmer(2022-01-12 20:27 작성됨)
답변 정말 감사합니다. 덕분에 잘 이해가 되었습니다. 
다만 3번 질문에서 제가 이해한 것이 맞는지.. 확인을 받고 싶습니다.

1. 힙 영역은 스레드들이 공유하기 때문에 값이 바뀌는 메서드 정보를 힙 영역에 넣을 필요성이 떨어진다.

2. 영상에 나온 Person 클래스 실행흐름을 해석(object 생성자 실행 이후 person 클래스 실행흐름으로 돌아왔을 때)할 때


- local variable array의 0번째 index에 있는 this(person 인스턴스 객체의 참조값)를 읽어 operand stack에 push한다.
- 메서드 영역의 runtime constant pool에 있는 상수 24를 가져와 operand stack에 push한다. --- 특히 이 부분
- this와 상수 24를 operand stack에서 pop하여 힙 영역 안에 있는 인스턴스 변수의 값을 저장한다.

이렇게 해석할 수 있을까요?
아이콘코드라떼(2022-01-12 22:39 작성됨)
안녕하세요 코드라떼입니다 :)

1. 힙 영역은 스레드들이 공유(O)하기 때문에 값이 바뀌는 메서드 정보를 힙 영역에 넣을 필요성이 떨어진다.(필요성이 떨어지는건 알 수 없음, 이전 질문의 답변은 이해를 돕기 위한 예시 설명입니다)

너무 어렵게 생각하지 마시고 단순하게 메서드 정보는 메서드 영역에 저장한다는 것만 아시면 될듯합니다.

2. 영상에 나온 Person 클래스 실행흐름을 해석(object 생성자 실행 이후 person 클래스 실행흐름으로 돌아왔을 때)할 때


- local variable array의 0번째 index에 있는 this(person 인스턴스 객체의 참조값)를 읽어 operand stack에 push한다. (O)
- 메서드 영역의 runtime constant pool에 있는 상수 24를 가져와 operand stack에 push한다. --- 특히 이 부분 
2byte로 표현 가능한 값(-32,768 ~ 32,767)은 직접 상수 값을 push합니다. 그 이상의 값은 constant pool의 상수값을 push합니다.
- this와 상수 24를 operand stack에서 pop하여 힙 영역 안에 있는 인스턴스 변수의 값을 저장한다. (O)

감사합니다.
아이콘glimmer(2022-01-12 01:44 작성됨)
안녕하세요, 강의 중 질문이 있어서 질문을 드립니다.

1. 2:40~50초 즈음에 ref1 참조값을 ‘pop’한 후 참조값을 복사하여 operand stack에 push한다고 나오는데요, 이 과정에서 operand stack에 ref1 참조값이 1개가 남아야 하지 않나요? 이후 강의를 계속 들어보면 person 인스턴스의 age1, age2 값을 채운 후 참조값을 operand stack에 push한다는 것을 보면 1개가 남는 것이 맞아 보여서 질문드립니다.

2. ‘Ref1 참조값을 pop하여 person 인스턴스의 생성자 메서드를 실행’한다는 부분이 잘 와닿지 않습니다. 그러면 힙 메모리에 person 인스턴스(인스턴스 변수 포함)를 저장한 후 operand에 ref1 참조값을 push했다가 다시 pop하며 person 인스턴스의 생성자 메서드를 실행한다는 뜻인가요? // 만약 이 말이 맞다면, 참조값을 operand stack에서 push, pop하는 과정을 거쳐 생성자 메서드를 실행한다는 것을 받아들이면 되는건가요? (그렇게 하는 이유가 있다면 알고 싶습니다. Ex. 초기화 과정이 이런 방식으로 일어난다?)

3. 영상에서의 Person 클래스가 이해가 잘 가지 않습니다. 제가 고민한 바로는 ‘영상에서의 person class가 사실은 public class person(24, 54)로 생성자를 위한 값이 들어가고, 밑에서 매개변수 2개(ex. int a, int b)를 갖는 생성자가 명시된 형태를 띈다.(ex. this.age1 = a, this.age2 = b)’라고 이해했는데 이게 맞는 것인가요?

4. Person 클래스에서 this가 local variable array에 들어가 있는건 내부적으로 처리가 되어 있는 것인가요? 내부 원리를 잘 모르겠습니다.

5. Swap 메서드의 person.age2 = person.age1 부분에서 ref1, 54, ref1, 24 이렇게 ref1 참조값이 2번 operand stack에 담겼다 pop되는 이유가 ‘person 인스턴스에 있는 age1(또는 age2) 값을 읽어내거나 수정하기 위해서는 person 인스턴스의 참조값이 필요하기 때문이다(접근하기 위해서)’라고 이해하면 될까요?

강의 감사드립니다.
아이콘코드라떼(2022-01-12 14:59 작성됨)
안녕하세요. 코드라떼입니다 :)

1. 2:40~50초 즈음에 ref1 참조값을 'pop'한 후 참조값을 복사하여 operand stack에 push한다고 나오는데요, 이 과정에서 operand stack에 ref1 참조값이 1개가 남아야 하지 않나요? 이후 강의를 계속 들어보면 person 인스턴스의 age1, age2 값을 채운 후 참조값을 operand stack에 push한다는 것을 보면 1개가 남는 것이 맞아 보여서 질문드립니다.

1) 2:40~50초 즈음에 ref1 참조값을 'pop'한 후 참조값을 복사하여 operand stack에 push한다고 나오는데요, 이 과정에서 operand stack에 ref1 참조값이 1개가 남아야 하지 않나요?

답변: 2:40~50초 즈음 참조값을 'pop'한 후 ref1 참조값을 복사하여 Person 인스턴스의 참조값 2개를 operand stack에 두 번 푸쉬합니다. 그래서 ref1이 operand stack에 두 개가 됩니다. 그 부분은 영상에서는 말로만 설명하고 복사하고 push한 결과만 보여주었습니다. 정확히 알고 계셔야 하는 부분은 Frame마다 operand stack이 '별도'로 존재합니다. 
메인 메서드와 연관된 Frame의 operand stack에 저장된 참조값 둘 중 하나는 인스턴스에 접근하여 생성자를 실행하기 위해 사용되며, 나머지 하나는 이후에 Person person; 변수에 참조값을 저장하기 위해 사용됩니다.

2) 이후 강의를 계속 들어보면 person 인스턴스의 age1, age2 값을 채운 후 참조값을 operand stack에 push한다는 것을 보면 1개가 남는 것이 맞아 보여서 질문드립니다.

답변: Person 인스턴스의 생성자 흐름과 연관된 Frame과 메인 메서드의 흐름과 연관된 Frame의 operand stack은 서로 다릅니다 :)

2. ‘Ref1 참조값을 pop하여 person 인스턴스의 생성자 메서드를 실행’한다는 부분이 잘 와닿지 않습니다. 그러면 힙 메모리에 person 인스턴스(인스턴스 변수 포함)를 저장한 후 operand에 ref1 참조값을 push했다가 다시 pop하며 person 인스턴스의 생성자 메서드를 실행한다는 뜻인가요? // 만약 이 말이 맞다면, 참조값을 operand stack에서 push, pop하는 과정을 거쳐 생성자 메서드를 실행한다는 것을 받아들이면 되는건가요? (그렇게 하는 이유가 있다면 알고 싶습니다. Ex. 초기화 과정이 이런 방식으로 일어난다?)

1) 힙 메모리에 person 인스턴스(인스턴스 변수 포함)를 저장한 후 operand에 ref1 참조값을 push했다가 다시 pop하며 person 인스턴스의 생성자 메서드를 실행한다는 뜻인가요?

답변: 맞습니다 :) 추가로 모든 클래스는 Object 클래스를 상속받으므로 상위 클래스인 Object와 연관된 생성자도 실행됩니다. 강의 내용에서는 이부분은 간단히만 설명하고 생략했습니다.

2) 만약 이 말이 맞다면, 참조값을 operand stack에서 push, pop하는 과정을 거쳐 생성자 메서드를 실행한다는 것을 받아들이면 되는건가요?

답변: 맞습니다 :) 초기화 과정이 이런 방식으로 실행됩니다. 

3. 영상에서의 Person 클래스가 이해가 잘 가지 않습니다. 제가 고민한 바로는 ‘영상에서의 person class가 사실은 public class person(24, 54)로 생성자를 위한 값이 들어가고, 밑에서 매개변수 2개(ex. int a, int b)를 갖는 생성자가 명시된 형태를 띈다.(ex. this.age1 = a, this.age2 = b)’라고 이해했는데 이게 맞는 것인가요?

잘못 이해하신 것 같습니다. 영상에선 생성자가 명시된 형태를 가지고 있지 않습니다.
자바 가상 머신 구현체마다 다르겠지만 인스턴스를 좀 더 쉽게 이해하기 위한 방법으로 이렇게 보시면 쉬울듯 합니다

Heap에 저장된 Person 인스턴스
참조값 #2915(예시)
--------------------------
| int age1 (Person) |
| int age2 (Person) |
--------------------------
Person 인스턴스는 메모리 공간에 위와 같이 적재 합니다. (메타 데이터 생략)
클래스의 생성자와 메서드 정보는 별도의 메모리 공간에 적재된다고 보시면 됩니다.
생성자의 로직과 메서드내에서 사용하는 정보는 어떤 인스턴스든 동일하므로 Heap에 저장하지 않습니다.
메서드나 생성자내에서 인스턴스마다 사용하는 참조값이 다르니 Heap에 같이 저장해야 하는게 아닌가 생각할 수 있지만 아닙니다.

만약에 이러한 코드가 있다고 가정해봅시다.

class Person {
    …
    public void setAge(int age) {
        this.age1 = age; 
    }
}

Person person1 = new Person();
Person person2 = new Person();

person1에 저장된 참조값 #2945
--------------------------
| int age1 (Person) |
| int age2 (Person) |
--------------------------
person2에 저장된 참조값 #2990
--------------------------
| int age1 (Person) |
| int age2 (Person) |
--------------------------

setAge 메서드 내에서 사용하는 age1 변수에 접근하기 위한 this는 인스턴스에 따라 서로 다를 수 있습니다.

class Person {
    …
    public void setAge(int age) {
        #2945.age1 = age; <— 이런거 아닙니다
    }
}
class Person {
    …
    public void setAge(int age) {
        #2990.age1 = age; <— 이런거 아닙니다
    }
}

그러나 착각할 수 있는 부분이 메서드내에서 접근하는 인스턴스 변수 정보가 다르므로 Heap에 메서드 정보를 별도로 저장해야 하는거 아닌가 생각할 수 있으나

class Person {
    …
    public void setAge(int age) {
        메서드가 실행되는 인스턴스의 참조값을 가져온다.age1 = age;
    }
}
this.age1에서 this 명령어의 의미가 'Frame내의 인스턴스의 참조값'이라고 한다면 this는 절댓값이 아니므로 굳이 메서드의 정보를 Heap에 저장할 필요가 없습니다.

설명이 어렵긴 한데 Heap에 저장되는 것은 인스턴스 변수와 메타 데이터가 저장된다고만 생각하시면 될듯합니다.

https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5.4
Method Area 해당 부분을 참고해보세요 :)


4. Person 클래스에서 this가 local variable array에 들어가 있는건 내부적으로 처리가 되어 있는 것인가요? 내부 원리를 잘 모르겠습니다.

this 적재 시점은 local variable array 초기화 시점으로 보시면 될 듯 합니다.(Stack Frame 적재 시)

5. Swap 메서드의 person.age2 = person.age1 부분에서 ref1, 54, ref1, 24 이렇게 ref1 참조값이 2번 operand stack에 담겼다 pop되는 이유가 ‘person 인스턴스에 있는 age1(또는 age2) 값을 읽어내거나 수정하기 위해서는 person 인스턴스의 참조값이 필요하기 때문이다(접근하기 위해서)’라고 이해하면 될까요?

맞습니다 :) 접근하기 위해서는 인스턴스의 참조값이 필요합니다.
아이콘bng4535(2022-01-01 23:23 작성됨)
1.
public static void main(String[] args){
....
} 
가 실행될 때, 영상에서 local variable array에서 args에 해당하는 메모리주소에 ref0이 들어가 있는데 이건 operand를 거치지 않고 처음부터 그냥 저장이 되는건가요? 어떤 원리로 저장이 되어있는건지 궁금해요

2. 그리구 생성자가 실행될 때 argument가 없는데 this포인터를 저장하는 메모리가 할당되어 있는 것도 왜 그런것인지 알고 싶어요

3. 객체의 변수에 접근할 때 객체를 가리키는 포인터를 이용하던데, 그 포인터를 통해 객체의 위치로 이동한다음 그 객체 내의 변수의 위치는 어떻게 아는건가요? 그림에 있는 거보다 더 많은 정보가 오고가는 건가요??
아이콘코드라떼(2022-01-02 13:46 작성됨)
안녕하세요. 코드라떼입니다 :)

1.
프로그램이 실행되면 항상 Main StackFrame에 String[] args 매개 변수가 할당되고, 전달되는 값이 있다면 Heap 메모리에 배열의 공간(heap)을 할당하여 저장됩니다.
에디터를 이용하거나 또는 프롬프트, 터미널로 자바 프로그램을 실행할 때 익숙하시면 다음과 같이 실험해 볼 수 있습니다.
만약에 자바 프로그램을 실행할 때 "code"와 "latte" 값을 전달하려면 아래와 같이 작성하면 됩니다.
> java Main "code" "latte"
만약에 이렇게 값이 전달되면 String[] args 매개변수에는 길이가 2이고 "code", "latte"값을 저장하는 배열이 할당됩니다.
만약에 값이 전달되지 않을 경우는 길이가 0입니다.

operand stack 부분과 관련하여 바이트코드 상으로는 operand stack의 연산 과정을 거쳐서 args 매개변수에 저장하는 부분은 작성되어 있지 않습니다.
자바 가상 머신이 프로그램 시작시 내부적으로 처리하는 것으로 보입니다.

2.
this 포인터는 argument와 상관없이 '자기 자신을 가리키는 포인터'입니다. 

예를들어 아래와 같은 코드가 있을 때
public class Person {
    public int age1 = 54;
    public int age2 = 24;
    
    public setAge1(int age) {
        age1 = age;
    }
}
Person 인스턴스가 메모리에 할당되면 참조값이 #41512라고 가정해봅시다.
동영상에서는 this 또는 ref로 표기했었는데요. 
StrackFrame이 Person 내에서 동작하는 경우 자기 자신을 가리키는 this(#41512)로 표기하고 외부에서 Test 인스턴스를 접근할 때는 ref(#41512)로 표기했습니다.

만약에 setAge1(..) 호출 시 age1 인스턴스 변수에 접근하려면 StackFrame 내에 Test 인스턴스에 접근할 수 있는 포인터가 필요합니다.
코드상으로는 age1이지만 사실 this.age1 또는 ref.age1이라고 보면 됩니다.
결론적으로 this 참조값을 통해 Person 인스턴스내에 있는 age1 변수에 접근합니다.

3.
객체 내의 변수의 위치는 바이트코드에서 드러나지 않으며 자바 가상 머신에 의해 내부적으로 처리됩니다.
그림에 있는 것은 바이트코드의 명령어 기준으로 동작 원리를 설명한 것이며, 구현 원리나 더 정확한 절차를 알기 위해서는 가상 머신 구현체를 봐야 합니다.

감사합니다 :)

이용약관|개인정보취급방침
알유티씨클래스|대표, 개인정보보호책임자 : 이병록
이메일 : cs@codelatte.io|운영시간 09:00 - 18:00(평일)
사업자등록번호 : 824-06-01921|통신판매업신고 : 2021-성남분당C-0740
주소 : 경기도 성남시 분당구 대왕판교로645번길 12, 9층 24호(경기창조혁신센터)