2. 스택(Stack) 메모리와 힙(Heap) 메모리
스택에는 함수 내에 존재하는 로컬 변수가 저장되고, 힙에는 클래스 내에 존재하는 인스턴스 변수가 저장된다. 실제 객체를 생성할 때 스택과 힙에 어떻게 할당될까? (자바의 메모리 영역이 스택과 힙만 있는 것은 아니지만 객체 생성 시 가장 관련이 있는 것이 두 메모리이다.)
객체가 생성될 때 메모리에서 어떤 일이 일어나는지 살펴보기 위해 앞서 살펴본 코드를 조금 수정한다.
먼저 Developer 클래스는 다음과 같이 약간 수정하여 먹고, 자고, 코딩하는 함수를 제거하였다.
public class Developer { private String name; private int age; public Developer() { System.out.println("[default] Developer Object is created!"); } public Developer(String name, int age) { System.out.println("[name : " + name + " age : " + age + "] Developer Object is created!"); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } |
HelloWorld 클래스는 다음과 같이 수정하였다.
public class HelloWorld { public static void main(String[] args) { String name = null; int age = 0;
Developer javaDeveloper = new Developer(); javaDeveloper.setName("Tom"); javaDeveloper.setAge(23); name = javaDeveloper.getName(); age = javaDeveloper.getAge(); System.out.println("name = " + name+ ", age = " + age);
Developer kotlinDeveloper = new Developer("Jerry", 20); name = kotlinDeveloper.getName(); age = kotlinDeveloper.getAge(); System.out.println("name = " + name+ ", age = " + age); } } |
[default] Developer Object is created! name = Tom, age = 23 [name : Jerry age : 20] Developer Object is created! name = Jerry, age = 20 |
이제 위 코드가 실행되면서 객체가 생성될 때 실제 스택과 힙에 할당되는 값이 무엇인지 하나씩 살펴보겠다.
String name = null; int age = 0; |
name, age는 main 함수 내에 선언된 로컬 변수이다. 로컬 변수는 스택에 저장된다고 했다. 따라서 다음과 같이 스택에 로컬 변수가 생성된다. 아직 힙에는 아무런 변화가 없다.
String name = null; int age = 0;
다음은 Developer 객체를 생성하는 부분이다. 해당 부분을 조금씩 나눠 살펴보자. 먼저 Developer javaDeveloper 부분이 실행될 때 스택에 로컬 변수 javaDeveloper가 생성된다.
Developer javaDeveloper = new Developer(); |
Developer javaDeveloper
다음으로 객체가 실제 생성되는 new Developer()로 인스턴스화가 되면서 실제 힙에 Developer 클래스의 요소들이 생성된다. 이때 생성된 힙 메모리 주소는 0x100번지라고 가정한다. 또한 함수명은 생략하고 함수라고만 표기하였다.
Developer javaDeveloper = new Developer(); |
new Developer
객체가 기본 생성자를 통해서 만들어졌기 때문에 추가적인 작업이 없이 마무리되었다. 따라서 최종적으로 아래의 구문이 끝나게 된 것이다. 이때 스택에 있는 javaDeveloper 변수에 객체의 위치 정보인 힙의 주소가 할당된다.
Developer javaDeveloper = new Developer(); |
Developer javaDeveloper = new Developer();
setter 함수를 통해서 인스턴스 변수에 값을 할당하면 힙에 해당 값이 할당된다.
javaDeveloper.setName("Tom"); javaDeveloper.setAge(23); |
javaDeveloper.setName("Tom"); javaDeveloper.setAge(23);
반대로 getter 함수를 통해서 인스턴스 변수의 값을 로컬 변수에 할당할 수도 있다.
name = javaDeveloper.getName(); age = javaDeveloper.getAge(); |
name = javaDeveloper.getName(); age = javaDeveloper.getAge();
코드를 보면 하나의 객체를 더 만드는데 기본 생성자가 아니라 오버로딩한 생성자를 사용했다. 이때도 로컬 변수 생성하는 단계에서는 차이점이 없다.
Developer kotlinDeveloper = new Developer("Jerry", 20); |
Developer kotlinDeveloper
다음으로 객체를 생성하는 과정도 같다.
Developer kotlinDeveloper = new Developer("Jerry", 20); |
new Developer
그리고 오버로딩된 생성자를 사용하면서 나타나는 차이점이 있다. 이 경우는 곧바로 인스턴스 변수를 생성자의 인자 값으로 초기화하기 때문에 인스턴스 변수의 값이 최종적으로 다음과 같이 된다.
Developer kotlinDeveloper = new Developer("Jerry", 20); |
new Developer("Jerry", 20)
최종적으로 해당 구문이 모두 실행되면 kotlinDeveloper에 힙 메모리 주소가 할당된다.
Developer kotlinDeveloper = new Developer("Jerry", 20); |
Developer kotlinDeveloper = new Developer("Jerry", 20);
나머지 getter, setter 함수를 사용하는 부분은 동일하다. 따라서 생략한다.
'프로그래밍 > JAVA' 카테고리의 다른 글
자바의 객체 (2) (0) | 2020.07.20 |
---|---|
자바의 객체 (1) (0) | 2019.03.19 |
원형 큐(Circular Queue) (0) | 2016.12.08 |
DatagramSocket Example (0) | 2016.12.03 |
Implement Stack (0) | 2016.12.01 |
LinkedList Implementation (0) | 2016.11.29 |
How to get google server time (URLConnection Example) (0) | 2016.11.27 |