프로그램과 프로세스, 스레드, 그리고 Static
프로그램(Program)과 프로세스(Process), 그리고 스레드(Thread)의 차이는 아래 그림을 확인해보자.
위의 그림에서 만들어진 프로세스와 스레드를 그림으로 나타내면 다음과 같다.
아래는 프로세스와 스레드의 대략적인 개요도이다.
스레드는 Stack에 저장된다.
이때 Data ,Heap, Stack에 각각 저장되는 데이터의 정보를 구분하자면 아래와 같다.
Static | Heap (동적 메모리 할당) |
Stack (정적 메모리 할당) |
|
저장되는 데이터 | 전역(클래스) 변수, Static (정적 변수) |
인스턴스(객체) 변수, 멤버변수 |
지역 변수, 매개 변수 |
생성 시점 | 프로그램 시작 시 | 객체 생성 시 | 메소드 실행 시 |
제거 시점 | 프로그램 종료 시 자동소멸 | 더 이상 사용되지 않을 경우 (= 사용 빈도수가 적을 경우), Gabage Collector(GC)에 의해 수거 | 메소드 종료 시 자동소멸 |
* 참고 : 멤버변수는 선언 위치가 '클래스 영역'이고, 지역변수는 선언 위치가 '메소드나 생성자 내부'이다.
* 생성 시점을 기준으로 이해하면 변수들의 의미를 보다 잘 파악할 수 있다.
여기서 Static 변수와 non-Static 변수가 갖는 특성은 다음과 같다.
Static | Non-Static | |
공유 | 다른 객체들과 공유 | 다른 객체들과 공유 X |
객체를 생성하기 전에 | 사용 가능 | 사용 불가능 |
언제 실행되냐 | main() 함수가 실행되기도 전에 이미 실행 |
객체가 생성되면 실행 |
클래스당 | 1개만 생성 | 객체가 생성되는 만큼 생성 |
때문에 Static은 사원번호, 고객번호 처럼 여러 객체가 공유해서 사용하는 변수를 선언할때 활용하기 적합하다.
관련 문제
위 코드를 보면 static 메소드 내부의 employeeName = "Lee"는 에러가 발생하고, 반면 public 메소드 내부의 serialNum = 1000;은 에러가 발생하지 않는다.
static은 프로그램이 시작되는 동시에 생성되지만 public 메소드의 경우 해당 인스턴스가 생성되어야 따라서 생성된다.
때문에 static 메소드 내부에 있는 employeeName은 시작과 동시에 메모리를 할당받지 않기 때문에 에러가 발생하고, 반면 public 메소드 내부에 있는 serialNum은 static 변수이기 때문에 해당 메소드를 호출하는 순간 이미 해당 인스턴스가 메모리를 할당받았다는 뜻이 되므로 에러가 발생하지 않는다.
참고 사이트
JAVA에서의 메모리 관리 (Woopi의 블로그)
Java - 클래스 생성, 인스턴스와 참조변수, 힙 메모리 (윤제니)