ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • JAVA의 static
    개발/안드로이드 2019. 4. 3. 21:50

    0. JAVA Static

    절차 지향인 C언어에서 static 변수는 함수 또는 변수를 작성 중인 파일 내에서만 사용하고 싶을 때만 사용하기 때문에 사용법이 비교적 간단했는데 JAVA에서는 객체지향 개념과 연관되어 있어 사용 시 다소 주의가 필요하다. 이번 포스트에서는 JAVA 언어에서 static의 쓰임새에 대해서 정리를 해본다.


    1. Static/Non-static 멤버

    자바에서는 클래스 내의 함수 또는 변수를 멤버(Member)라고 통칭해서 부르며 앞에 static 변수를 붙이면 static 멤버, 붙이지 않으면 Non-static 멤버로 분류한다.

    public class MainActivity extends AppCompatActivity {
      static int staticVar = 0;       // static Member
      static void staticMethod() {}   // static Member
    
      int nonStaticVar = 0;           // Non-static Member
      void nonStaticMethod() {}       // Non-static Member
    }
    

    Static 멤버는 별도의 객체 생성과정 없이 바로 사용할 수 있고 클래스당 하나씩만 존재해 동일한 클래스로 생성된 복수의 객체가 동일한 변수의 값을 공유하게 된다. C/C++의 전역 변수와 함수와 원리가 비슷한데 이와 같은 특징은 Static 멤버들이 객체를 생성하기 전에 이미 메모리에 로딩되며 객체가 제거와 상관없이 프로그램이 종료될 때까지 메모리에 남아있는 구조적인 특징 때문에 발생한다.

    Non-Static 멤버는 Static 멤버와 원리가 정반대다. 반드시 객체를 생성한 후에 사용할 수 있으며 생성된 객체별로 멤버의 값이 다를 수 있다. 이는 멤버 인스턴스들이 객체의 생명주기에 따라서 메모리에 생성되고 제거되는 원리 때문이다. Non-Static 멤버들은 객체지향적인 관점에 근거해서 동작하는 인스턴스다.


    2. 사용 예시

    2.1 Singleton Pattern

    프로그램에서 클래스당 하나의 객체만 사용하도록 유도하는 Singleton Pattern은 static을 적절히 사용한 대표적인 예다. getInstance 함수를 별도의 객체 생서 없이 호출할 수 있도록 static 멤버로 선언했으며 클래스 변수인 instance도 static으로 선언해 여러개의 객체가 생성되더라도 동일한 객체만 리턴할 수 있도록 했다.

    public class Singleton {
      private static Singleton instance;
      private LazySingleton() {}
      public static synchronized Singleton getInstance() {
          if(instance == null) {
              instance = new Singleton();
          }
          return instance;
      }
    }
    

    2.2 Math

    private int getAbs(int a) {
    	return Math.abs(a);
    }

    별다른 객체 생성 없이 바로 실행하는 Math 클래스의 함수들은 모두 static 멤버들로 선언된 것들이다. JAVA는 객체지향 관점에 따라서 모든 함수들은 반드시 객체를 통해서 호출되기 때문에 위와 같이 static 함수를 적극적으로 활용해 라이브러리를 호출할 수 있도록 했다.


    3. 주의사항

    3.1 Out of Memory

    객체가 제거되도 static 멤버는 메모리에 남아있기 때문에 코드 상에서 별도로 처리해두지 않으면 모든 메모리 공간을 static 인스턴스가 차지하는 메모리 Leak이 발생할 수 있다.

    public class OomClass {
      static Vector oomVector;
      static void addOomVector(int a) {
          oomVector.add(a);
      }
      public OomClass() {
          for (int i = 0; i < 100000; i++)
              addOomVector(i);
      }
    }
    

    위의 OomClass는 생성 할 때마다 static 변수는 oomVector 벡터 클래스에 0~99999까지 엔트리를 추가하는데 OomClass 한 두 개 정도 생성할 때는 별 문제가 되지 않지만 그 수가 많아지면 메모리에서 차지하는 비율이 높아져 OOM이 발생할 수 있다.

    3.2 Static 함수의 제약사항

    Static 함수 내에서는 Static 멤버만 사용할 수 있고 this 호출이 불가능하다. 이런 제약사항은 역으로 Non-Static 멤버도 접근 할 수 있고 this를 호출 할 경우 어떤 문제점이 발생할지 예측해보면 이해하기 쉽다. Non-Static 멤버들은 객체가 생성되어야 메모리에 한자리 차지하게 되는데 객체 생성 없이 바로 호출되는 static 함수에서 생성 됐는지 확인되지 않는 멤버 변수들에게 접근한다면 이는 invalid access가 된다. 구조적인 특징에 대해서 다시 한번 생각해보게 된다.



    '개발 > 안드로이드' 카테고리의 다른 글

    안드로이드 Loader  (0) 2019.07.15
    onSaveInstanceState  (0) 2019.07.15
    안드로이드 Service  (0) 2019.03.19
    AsyncTask  (0) 2019.03.13
    ViewPager와 PageAdapter  (2) 2019.03.05

    댓글

Designed by Tistory.