Jun's note

[Java] 자바 메모리관리, 전역변수와 지역변수에 대해 본문

Programming/Java

[Java] 자바 메모리관리, 전역변수와 지역변수에 대해

junning 2022. 12. 15. 22:07
728x90

1. 배경

나는 코드 한줄을 적더라도 깊이있게 생각한 다음에 작성한다. 그러다 문득 전역변수, 정적변수, 지역변수는 어떻게 관리되는지 궁금해 찾아보았다. 자바도 하나의 가상머신을 통해 작동되기 때문에 메모리관리는 OS메모리관리와 비슷하다.

 

2. 정리

1) JVM 구조

출처: https://steady-coding.tistory.com/305

크게 5가지 영역으로 나눌수있다.

  • 메소드영역
    • 전역변수가 저장된다.
    • 스레드가 메소드영역에 있는 값을 공유할 수 있다. -> 여러 스레드가 동시에 하나의 공유변수의 값을 변경하면 문제가 발생하여 동기화 과정이 필요할 수 있다. -> 전역변수를 사용할때는 final 키워드를 되도록이면 사용하여 문제가 안생기도록 조심하자!
    • 소멸시기: 프로그램이 종료할때 메소드영역에 있는 변수들이 소멸된다.
  • 힙영역
    • 동적으로 할당된 변수, 참조타입 (reference type)이 저장된다. 즉 new()연산자로 정의된 모든 객체들이 저장된다.
    • Java 8이후로는 정적변수(static)도 힙영역에 관리된다. 즉 GC에 의해 관리된다는 말이다.
    • 힙영역에는 실제값이 저장되며, 스택에는 (변수이름+힙에 할당된 실제값의 메모리주소). 형식으로 저장된다.
    • 소멸시기: GC(Garbage Collector)을 통해 알아서 참조하지 않는 객체를 정리한다.
  • 스택영역
    • 지역변수, 매개변수, 리턴값, 리턴주소, 원시타입 (primitive type)이 저장된다.
    • 소멸시기: 함수가 끝나는 시점에 변수들이 소멸된다.
    • 스택은 힙보다 공간이 작기 때문에 stackoverflow가 발생하지 않도록 조심해야한다.
  • PC 레지스터
  • Native Method Stack

 

2) GC (Garbage Collector)

  • GC의 목적
    • '메모리 누수' 현상 방지를 위해
    • C나 C++은 메모리에 직접 접근하여, free()를 통해 메모리를 할당해주는 등 '메모리 누수' 현상을 방지하지만 자바는 GC를 통해 '메모리 누수'현상을 방지하며 프로그래머가 직접 메모리에 접근하지 못하게한다.
    • 자바는 OS의 메모리 영역에 직접적으로 접근하지 않고 JVM 이라는 가상머신을 이용해서 간접적으로 접근한다
  • GC의 대상
    • 객체가 참조되고 있는 않은 상태일때 GC가 알아서 정리한다.
  • GC알고리즘
    • GC알고리즘에는 여러종류가 있으며, Serial, Parallel, G1, CMC, Shenandoah, ZGC가 있다. 상황에 따라 GC방식을 선택해 자바에 설정할 수 있다.

GC 알고리즘 종류 / 출저: https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EA%B0%80%EB%B9%84%EC%A7%80-%EC%BB%AC%EB%A0%89%EC%85%98GC-%EB%8F%99%EC%9E%91-%EC%9B%90%EB%A6%AC-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%F0%9F%92%AF-%EC%B4%9D%EC%A0%95%EB%A6%AC#Eden_

3) String Constant Pool 

  • 힙영역에는 String Constant Pool이 있다.
  • 자바는 String 참조타입을 new연산자로 선언하지않고 실제 값이 동일하다면 heap에 있는 값을 공유하도록 지원한다. 이는 객체를 재사용하기 때문에 메모리 측면에서 성능이 좋다.
  • new연산자로 선언할 경우 String Constant Pool과 관련없이 그냥 heap에 새로운 객체를 할당하여 저장한다.
  • 참조타입에는 Long, Integer, String 등등 있지만 자바는 String만 동일한 값의 객체 공유를 지원하는 것 같다.

출처: https://code-lab1.tistory.com/130

 

4) 전역변수를 사용할까, 지역변수를 사용할까?

  • 전역변수
    • 장점
      • 변수를 전역으로 사용할 수 있기때문에 코드적 측면에서 깔끔하게 코드를 작성할 수 있다.
    • 단점 
      • 여러 쓰레드가 하나의 공유변수를 동시에 변경&접근하는 문제가 발생할 수 있음. -> 이 문제는 final+private을 통해 값이 변경되지 않도록하기
      • 전역변수는 프로그램 종료시 소멸되기 때문에 메모리 부족 현상이 발생할 수 있다. -> static을 통해 GC의 대상이 되도록하기
  • 지역변수
    • 장점
      • 함수가 종료될때 변수도 소멸되기 때문에 프로그램 전체 측면에서 볼때 전역변수보다 메모리측면에 이점이 있다. 그렇지만 지역변수나 매개변수 등이 많이 정의되면 stack 메모리도 overflow될 수 있으니 조심해야한다.
    • 단점
      • 자주 사용되는 변수도 지역변수로 정의해주면 코드적 측면에서 변수정의하는 부분이 비슷하니 깔끔한 코드작성이 어려울 수 있다.
  • 결론: 변수를 언제까지 사용할건지, 공유변수 동시 접근과 같은 이슈는 발생하지 않을 지 등 상황에 맞게 판단하여 사용하자!

 

5. 회고

지금 하는 고민이 사소하고 중요하지 않을 수 있지만, 작은것들이 쌓여서 더 발전적인 개발자가 된다고 생각한다. 그리고 지역변수, 전역변수, final, static 등과 같은 단순하고 간단한 것들을 지금 더 자세히 공부해놔야 이것이 좋은 습관으로 이뤄질 수 있기 때문에 조금은 느릴지라도 정확하게 깊이있게 아는것이 중요하다 생각한다.

계속계속 더 열심히 하자😊

'Programming > Java' 카테고리의 다른 글

[Java] 상수변수를 사용할때의 궁금증  (0) 2022.12.13
Comments