본문 바로가기

JAVA

JAVA의 메모리 구조, 멀티 스레드 공유 변수 문제

T메모리 구조

자바의 메모리는 코드 실행 영역과 데이터 저장 영역으로 나뉩니다.
데이터 저장 영역은 T메모리 구조를 가집니다.
T메모리 구조는 스태틱 영역, 스택 영역, 힙 영역으로 나뉘어 집니다.
 

스태틱 영역에는 클래스 관련 메모리가 올라갑니다.
 

JVM의 전처리 과정 (스태틱 영역)

- 모든 자바 프로그램은 반드시 java.lang 패키지를 포함하기 때문에 이 패키지를 스태틱 영역에 올려놓습니다.
- 다음으로 JVM은 개발자가 작성한 모든 클래스와 import 패키지 역시 스태틱 영역에 올려놓습니다.
 

스택 영역

- main() 메소드가 시작되면 스택 영역에 main() 스택 프레임이 형성됩니다.
- if문이나 반복문 같이 여는 중괄호를 만날 때마다 스택 프레임이 하나씩 생깁니다. (클래스 정의 괄호 제외)
- 닫는 중괄호를 만나면 그 스택 프레임은 사라지게 됩니다.
- 서로의 스택 프레임 안에 있는 지역 변수끼리는 접근이 불가합니다.
 
지역변수 - 스택 프레임에 종속적인 변수
전역변수 - 스택 프레임에 독립적인 변수
 

멀티 스레드 / 멀티 프로세스의 이해

멀티 프로세스는 자료 저장 영역에 다수의 T메모리를 사용
하나의 프로세스가 다른 프로세스의 T메모리 영역을 절대 침범할 수 없는 구조

멀티스레드는 스택 영역을 스레드 개수만큼 분할
스택 영역만 분할 했기 때문에 다른 영역은 공유해서 사용하는 구조
따라서 멀티 프로세스 대비 메모리를 적게 사용할 수 있습니다.
 

멀티 스레드에서 전역 변수 사용의 문제점

스레드1스레드2Action
전역 변수 A에 10 할당 전역 변수 A는 10을 저장
 전역 변수 A에 20 할당전역 변수 A는 20을 저장
전역 변수 A의 값을 출력 20 출력

전역변수를 사용하면 스태틱 영역에 메모리가 생깁니다. 이 자원을 공유하기 때문에 생기는 문제입니다. 이 문제를 해결하는 방법 중 하나인 synchoronized 방법이 https://hecoej.tistory.com/25 에 소개되어 있습니다.
 
 

힙 영역

객체들이 저장되는 곳입니다.

package inheritance03;

public class Animal {
  public String name;
  
  public void showName() {
    System.out.printf("안녕 나는 %s야.\n", name);
  }
}
package inheritance03;

public class Penguin extends Animal {
  public String habitat;
  
  public void showHabitat() {
    System.out.printf("%s는 %s에 살아.\n", name, habitat);
  }
}
package inheritance03;

public class Driver {
  public static void main(String[] args){
    Penguin pororo = new Penguin();
    
    pororo.name = "뽀로로";
    pororo.habitat = "남극";
    
    Animal pingu = new Penguin();
    
    pingu.name = "핑구";
    //pingu.habitat = "EBS";
    
    pingu.showName();
    //pingu.showHabitat();
    
    //Penguin happyfeet = new Animal();
    }
  }

[그림 3-32]을 보면
스태틱 영역: java.lang, Driver클래스, Animal클래스, Penguin클래스
스택 영역: main() 스택 프레임
이때, penguin 클래스의 인스턴스만 힙 영역에 생긴 게 아니라 Animal 클래스의 인스턴스도 함께 힙 영역에 생김
(원래 모든 클래스의 최상위 클래스인 Object 클래스의 인스턴스도 함께 생성되나 그림에서 생략)
pingu 객체 참조 변수가 가리키고 있는 것은 Animal 인스턴스 Animal pingu = new Penguin(); 입니다.