
모각소 2주차 1번째
오늘은 "객체지향 프로그래밍 및 실습"시간에 자세하게 배우지 않았던 java의 메모리 구조에 대해서 공부해 보았다.
CS관련 지식의 중요성은 개발에 대해서 배울 때마다 항상 느끼고 있으므로, 잊지 않게 꾸준히 복습해놓도록 하자.

자바의 메모리 구조는 크게 메서드 영역, 스택 영역, 힙 영역 3개로 나눌 수 있다.
좀 더 자세하게 들어가보면

##참고
스택 영역은 더 정확히는 각 쓰레드별로 하나의 실행 스택이 생성된다. 따라서 쓰레드 수 만큼 스택 영역이 생성되는 것이다.
-> 시스템 프로그래밍 및 실습에서 배웠던 멀티스레딩을 잘 생각하자. stack 영역은 각 프로세스마다 할당이 되었지만, text, data, heap 영역은 공유해서 사용했다.

즉 메서드를 호출하면, 메서드 영역으로 점프하여 지정한 메서드가 실행되는 모습이다.
위에 나왔던 자바 메모리 구조에서 static 영역은 메서드 영역에 존재하는 것을 보았을 것이다.
하지만 내가 들었던 의문은
결국 지역 변수로 선언이 되니, 인스턴스로 선언되면 heap영역, 메서드로 호출되어 사용되면 stack 영역으로 들어가야하는 것이아닌가?
라는 생각을 했다.
이에 대한 답변으로 먼저 간단한 코드를 확인하겠다.
public class Data3 {
public String name;
public static int count; //static
public Data3(String name) {
this.name = name;
count++;
}
}
Data3 클래스 코드
public class DataCountMain3 {
public static void main(String[] args) {
Data3 data1 = new Data3("A");
System.out.println("A count=" + Data3.count);
Data3 data2 = new Data3("B");
System.out.println("B count=" + Data3.count);
Data3 data3 = new Data3("C");
System.out.println("C count=" + Data3.count);
}
}
위 코드는 3번의 생성자를 호출하여 3개의 인스턴스를 만들어준 모습이다.
실행 결과

위 결과로 알 수 있는 점은 static을 사용하면 인스턴스가 다른 객체에서도 공유된 변수를 구현할 수 있다는 것이다.

1. 개발자가 인스턴스를 생성할 때마다, 각 인스턴스에 저장되어 있는 count++를 실행
2. count 는 static으로 선언 된 클래스 변수이므로, 메서드 영역에 접근하여 count의 수를 증가
즉, 모든 인스턴스에서 같은 주소공간을 가르키는 변수를 사용해야하기 때문에 메서드영역에 저장한다. 라고 답변하면 되겠다.
같은 느낌으로 정적 메서드 또한 메서드 영역 중 static 영역에 저장되어 있으므로 클래스.(메서드이름)으로 바로 사용할 수 있다.
하지만, 정적 메서드는 언제나 사용할 수 있는 것이 아니다.
왜? 정적 메서드는 인스턴스의 기능을 사용할 수 없을 까?
package static2;
public class DecoData {
private int instanceValue;
private static int staticValue;
public static void staticCall() {
//instanceValue++; //인스턴스 변수 접근, compile error
//instanceMethod(); //인스턴스 메서드 접근, compile error
staticValue++; //정적 변수 접근
staticMethod(); //정적 메서드 접근
}
public void instanceCall() {
instanceValue++; //인스턴스 변수 접근
instanceMethod(); //인스턴스 메서드 접근
staticValue++; //정적 변수 접근
staticMethod(); //정적 메서드 접근
}
private void instanceMethod() {
System.out.println("instanceValue=" + instanceValue);
}
private static void staticMethod() {
System.out.println("staticValue=" + staticValue);
}
}
정적 메서드는 클래스의 이름을 통해 바로 호출할 수 있다. 그래서 인스턴스처럼 참조값의 개념이 없다. 특정 인스턴스의 기능을 사용하려면 참조값을 알아야 하는데, 정적 메서드는 참조값 없이 호출된다. 따라서 정ㄹ적 메서드 내부에서 인스턴스 변수나 인스턴스 메서드를 사용할 수 없다.
##참고: 객체의 참조 값을 직접 매개변수로 전달하면, 정적 메서드도 인스턴스의 변수나 메서드를 호출 할 수 있다.

오늘은 java 메모리 처리에 대해서 공부했다. 면접 때 CS지식이나 언어에 대한 이해가 필요하다고 하는 것에 대해서 처음에 이해가 안갔지만(개발만 잘하면 될 줄 알았다), 모각소를 통해서 같이 공부해나갈때마다 막히는 부분을 보면 결국 처음보는 문법이나 CS 지식 부족이 문제였다. 주중에 혼자 개발하고, 모각소 하는 시간은 언어에 대한 이론 공부를 하는 것도 서로 공유할 수 있을 것 같아서 좋겠다는 생각을 했다. 오늘도 잘 견뎌냈다.