우당탕탕 개발_𝒍𝒐𝒈

static에 대해서 본문

대외 활동/데브코스

static에 대해서

hojeong01 2024. 7. 20. 16:45

우선 static을 관리하는 메모리는 어디인지 그림으로 보고 넘어가자!


자바의 메모리 구조

  • Method 영역 : 클래스의 정보, static 영역, 상수 풀을 보관하는 영역, 프로그램을 실행하는 데 필요한 공통데이터를 관리하며 프로그램의 모든 영역에서 공유됩니다.  
  • Stack영역 : 실제 프로그램이 실행되는 영역으로 스레드만큼 스택영역이 생성됩니다. 자바 파일 실행 시 하나의 스택이 실행되며 스택 속에는 메서드 호출, 지역변수, 매개 변수, 중간 연산 결과등을 포함합니다. 
  • Heap 영역 : 객체(인스턴스)가 생성되는 영역으로 예약어  new를 사용하여 생성된 것들이 힙 영역 속에 들어온다. 따라서 배열 또한 힙 영역에 해당된다.  GC가 이루어지는 주요 영역이다.

 

static은 Method 영역에 위치한다는 것 확인할 수 있다! 


 

#1. Method 영역

  • Class 정보 : 클래스 생성 코드, 필드(인스턴스 변수), 생성자 코드, 메서드등 모든 실행 코드들이 포함된다. 
  • static 영역 (정적 변수, 클래스 변수)
  • Constant Pool (상수 풀) : (추가 공부 후 내용 추가)

 

 

 

 

 

 

 

 


❓static 영역 (정적 변수/ 클래스 변수)

- static은 멤버 변수와 메서드에 사용된다. 우선 static 변수에 대해 먼저 알아보자

 

# 필드의 종류

static의 유무에 따라 필드를 다음과 같이 구분할 수 있다.

static ❌ -> 인스턴스 변수
⭕ -> 클래스 변수

 

더보기

필드? : 간단히 말해  코드창에서 class 선언부 바로 아래 부분이다


  • 인스턴스 변수

- 객체를 생성해야 사용이 가능하며 객체에 소속되어있다. 따라서 객체가 생성될 때마다 새롭게 만들어진다.

 

(예제 1) total user 출력하기

public class Data2 {

    private String userName;
    private int totalUser;

    public void total(String userName){
        this.userName = userName;
        totalUser++;
        System.out.println("현재 누적 멤버 :"+totalUser);
    }

- username, totalUser 모두 인스턴스 변수로 지정하였다.

- 매개변수로 유저의 이름을 받으면 totalUser의 값이 1씩 증가되는 기능이 담긴 메서드를 작성하였다. 

public class DataCountMain2 {
    public static void main(String[] args) {
        Data2 user1 = new Data2();
        user1.total("김하나");

        Data2 user2 = new Data2();
        user2.total("김두리");

        Data2 user3 = new Data2();
        user3.total("김서이");
    }

- 위 코드의 출력 결과는 아래와 같다.

 

 

 

 

- 계획과 달리 누적 멤버의 수가 오르지 않았다.

 

이는  heep 영역에 user1, user2, user3의 객체가 생성될 때 인스턴스 변수가 새롭게 생성이 되면서 나타난 결과로 볼 수있다. 

아래의 그림과 같이 totalUser 변수 또한 인스턴스 변수로 인스턴스가 생성될 때마다 새롭게 만들어진다.

이 문제를 해결하기 위해선 하나의 totalUser에 모든 객체들이 접근할 수 있어야 했으며,   static을 사용하면 tatalUser를 공용으로 만들 수 있다. 


  • 클래스 변수

- 인스턴스와 무관하게 클래스에 바로 접근하여 사용가능하다. 

- 클래스 자체에 소속되어 있기 때문에 자바 프로그램을 실행할 때 실행되어 하나의 변수가 각 인스턴스에 공유된다.

(static은 메서드 영역(공용 공간)에서 관리하기 때문에 인스턴스 사이에서 공용으로 사용된다라고 이해하면 될 것 같다.)

 

위 코드를 다시 보자

public class Data2 {

    private String userName;
    private int totalUser; // --> static 변수로 변경하기 
    
    
public class Data2 {

    private String userName;
    private static int totalUser;

 

출력 결과

-기대했던 대로 total 기능이 작동되는 것을 확인할 수 있다. 

이는 클래스 변수의 특성으로 메서드 영역에서 관리되고 있기 때문에 인스턴스의 생성과 무관하게 한 개의 클래스 변수에서 각 인스턴스로 공유된 결과라고 설명할 수 있다.

⭐변수와 생명주기
지역 변수 ➡️ 인스턴스 변수 ➡️ 클래스 변수

지역변수 (메서드가 종료됨과 동시에 종료)

인스턴스 변수 (더 이상 참조하는 인스턴스가 존재하지 않을 때 GC가 작동)
클래스 변수 (JVM 종료 시 종료

 

 

클래스 변수(static 변수)는 메모리 상에서 먼저 호출되어 가장 오랜 시간 남아있기 때문에 정말 필요한 경우에 사용하는 것을 추천한다. 

 

개인적으로  static의 성격을 잘 보여줄 수 있는 패턴이 singleton이라는 생각이 든다. 강사님께서 static변수와 함께 설명해 주신 이유를 singleton 패턴에 대해 추가로 공부하게 되면서 이해하게 되었다. 

아래의 링크로 남기겠다!  

2024.07.20 - [대외 활동/데브코스] - singleton 패턴

 

singleton 패턴

싱글톤 패턴이란?하나의 클래스에 오직 하나의 인스턴스를 만들고 그것을 계속 재사용하는 패턴이다.  보통 데이터베이스 모듈에 많이 사용한다고 한다.오늘은 강의 시간에 배운 내용 +a으로

hojeong016.tistory.com