220706 TIL static이 뭔지는 알고 쓰자

짧게 나의 상태를 말하면 어제보다 조금 아주 조오금 나아졌다.

오늘 낮에 병원에 가서 수액도 맞고 해서 열이 많이 내렸다. 하지만 목은 더 아파졌다. 어제는 뭘 먹거나 침 넘길 때는 안 아팠는데 오늘은 물을 먹든 뭐를 먹든 목구멍에 넘기려 하면 고통도 같이 온다.

병원 가서 코로나 검사를 또 했는데 이번에도 음성이 나왔지만, 모든 증상이 나를 코로나라고 가리키고 있다..

나 코로나 걸린 건가..?

Static 왜 써?

매번 intellj 킬 때 가장 먼저 쓰는 public void static main(String[] args) 에서 static을 알아보자

지금까지는 그냥 저 문장을 써야 프로그램이 실행되니까 계속 써온 느낌이었다면 이제는 알고 쓰기 위해서 정리를 해봤다.

 

Static

static의 의미는 “정적인”, ”고정된”이라는 의미이다. static을 사용해서 생성된 변수, 메서드들은 static영역에 할당이 된다.

static영역의 특징은 Garbage Collector가 관여를 하지 않고, 모든 객체가 메모리를 공유한다.

멤버 변수 중 모든 인스턴스에 공통된 값을 유지해야 할 때 static을 사용한다.

Garbage Collector란?

일단 간단히 말하면 메모리를 관리할 때 이 Garbage Collector가 자동으로 필요 없는 메모리를 제거해준다.

그런데 static영역에서는 Garbage Collector가 관여하지 않기 때문에 static을 막 쓰다 메모리가 많이 쌓이다 보면 프로그램의 성능에 안 좋은 영향을 끼친다.

 

Garbage Collector에 대해 더 쉬운 이해를 위해 아주 잘 설명된 예시를 가져왔다.

컴퓨터가 일을 할 때도 처리할 정보들을 올려놓을 공간이 필요해요.

이게 조리대로 비유한 메모리에요. 조리대가 넓으면 넓을수록, 더 많은 종류의 요리를 동시에 더 많이 할 수 있겠죠.
컴퓨터를 살 때 램을 보는 이유에요. 여러분이 코드를 짜는건 컴퓨터의 주방장에게 레서피를 써주는거에요.

코드에 작성하는 변수들, 함수들, 객체들이 메모리 공간을 차지하는 요소들, 조리대에 얹어지는 재료와 도구가 되는거죠.

그런데 이 주방장은 자기주도적이질 못해요. 레서피대로 하다 조리대가 꽉 차면 그냥 멘탈이 나갑니다.  뻗어버려요.

중간중간 치워줘야겠죠. 그래서 자바를 비롯한, 새로운 언어들에는 가비지 컬렉터란걸 도입하기 시작했어요.

아까 그 센스있는 조수같은 로보트가 프로그래머가 일일이 하던 일을 대신해주는거죠.

이렇게 메모리를 알아서 관리하는 언어들을 managed language라고 해요. 반대는 unmanaged language라고 하죠.

언어와 동작하는 환경마다 다르지만 특정 때에 특정 방식으로 필요없는 정보들, garbage들을 쓸어담아다 버려요.
더보기

출처: yalco.kr/04_garbage_collector/

static 변수

static변수는 인스턴스 변수처럼 객체가 new(인스턴스화) 될 때 생성되는 변수가 아닌, 프로그램이 시작되는 순간 동시에 생성되는 변수이고, 이는 프로그램이 끝날 때까지 메모리에 있는 변수이다. 즉 인스턴스의 생성과 상관없이 사용할 수 있는 변수이며, 딱 한 번만 생성되는 변수다.

static 변수 예시

count가 static으로 선언이 되지 않는다면??

인스턴스 변수는 클래스가 생성(new)이 될 때 메모리 공간이 할당된다.

public class Experiment {
  int count = 0;  // static 없음 

  public Experiment() {
    this.count += 1;
    System.out.println(this.count);
  }

  public static void main(String[] args) {
    Experiment experiment1 = new Experiment();
    Experiment experiment2 = new Experiment();
  }
}

// 출력결과
1
1

experiment1, experiment2 객체가 생성될 때 서로 다른 count의 메모리를 가리키고 있어서 count가 1만 증가한 것을 볼 수 있다.

 

count를 선언할 때 static을 붙여서 선언한다면?

public class Experiment {
  public static int count = 0; 

  public Experiment() {
    this.count += 1;
    System.out.println(this.count);
  }

  public static void main(String[] args) {
    Experiment experiment1 = new Experiment();
    Experiment experiment2 = new Experiment();
  }
}

// 출력결과
1
2

count가 static 변수로 선언되었기 때문에 count의 값이 공유되어서 experiment1, experiment2 따로 객체를 생성해도 같은 count를 가리키고 있다.

static 메서드

static 메서드도 static 변수와 개념 자체는 다르지 않다. 메모리에 메서드 하나를 고정적으로 두어서 사용이 가능하다. static 메소드는 객체 생성 없이 메소드 호출이 가능하다. 그리고 static메서드 안에서는 인스턴스 변수에 접근이 불가능하다.

즉 static method에서 사용하는 변수가 모두 static 변수여야 하는데 이렇게 되면 메모리가 많이 쌓여서 안 좋은 영향을 끼쳐서 static method는 지양하는 방식이다.

 

내가 생각하는 static을 사용해야 할 때

  1. 항상 값이 변하지 않을 경우 static을 사용하여 메모리의 이점을 얻을 때
  2. static을 사용한 변수는 같은 메모리에 변수 값이 저장되기 때문에 변수의 값을 공통적으로 유지되어야 하는 경우

액션플랜

static을 공부하다 생성자가 궁금해졌는데 생성자에 대해 공부하고 내일 블로그 글 쓰기 (todolist 완성하고 나서..)