ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [객체지향의 원리와 이해] (02) 자바와 절차적/구조적 프로그래밍
    개발/OOP, Design Pattern 2020. 12. 23. 01:16

    깃허브

    자바와 절차적/구조적 프로그래밍

    변수가 어떻게 메모리에 저장되고 사용되는지와 메서드가 어떻게 호출되고 메모리에 어떤 변화를 일으키는지 살펴본다.

    자바 프로그램의 개발과 구동

    JVM의 존재와 역할을 아는 것은 자바 개발 환경을 이해하기 위해 필수이다. JVM은 가상 기계이고 현실세계와 가상세계를 비교하면 다음과 같다.

    현실세계    - 가상세계
    SW 개발도구 - JDK (JVM용 SW 개발 도구)
    운영체제    - JRE (JVM용 OS)
    하드웨어    - JVM (가상의 컴퓨터)

    (윈도우 JDK) JDK는 javac.exe를 포함하고, 이를 통해 컴파일해서 만들어진 목적 파일을 자바 가상 기계가 실행한다.

    자바 메모리 구조

    메모리는 |코드 영역|데이터 저장 영역| 으로 나눌 수 있고, 그 중에 데이터 저장 영역은
    |스태틱 영역|
    스택 영역|힙 영역 으로 나눌 수 있다. (T자 메모리구조)

    자바에 존재하는 절차적/구조적 프로그래밍의 유산

    객체 지향 프로그래밍은 절차적/구조적 프로그래밍에 기반한다.
    절차적 프로그래밍을 한마디로 표현하면 goto를 쓰지 말라는 것이다. goto를 사용하게 되면 프로그램의 실행 순서가 복잡해질 가능성이 크다.
    구조적 프로그래밍은 함수를 쓰라는 말이다. 중복 코드를 한 곳에 모을 수 있고, 논리를 함수 단위로 분리해서 이해하기 쉬운 코드를 작성할 수 있다.
    goto는 제어 흐름을 이리 저리 이동시키기 위한 용도이고, 함수는 중복 코드 제거와 논리를 분할하기 위한 용도이다. 따라서 자바에서 절차적/구조적 프로그래밍의 유산은 제어이다.

    함수와 메소드의 차이

    둘은 같은 의미이다.. 객체 지향에서는 함수를 다르게 부르기 위해 메소드라고 부르기 시작했다고 한다. 거기서 오는 차이를 보면 함수는 클래스내에 위치할 필요가 없지만, 메소드는 클래스 안에 위치한 것이다.

    프로그램 실행 과정

    프로그램 실행과정을 보면 JRE가 먼저 프로그램 안에 main() 메소드가 있는지 확인한다.
    확인되면 가상 기계 JVM을 부팅되고 JVM이 목적 파일을 받아 실행한다.
    그 다음 JVM이 맨 먼저 하는 일은 전처리 과정이다. 프로그램에 실행에 필수적인 java.lang 패키지를 스태틱 영역에 놓는다.
    그 다음 JVM은 개발자가 작성한 모든 클래스와 임포트 패키지를 스태틱 영역에 놓는다.

    메소드 스택 프레임

    위에 언급한 T자 메모리 구조에는 스태틱, 스택, 힙 영역이 있다.

    스태틱 - 클래스의 놀이터  
    스택 - 메소드의 놀이터  
    힙 - 객체의 놀이터  

    라고 정의할 수 있다.

    스택 프레임은 클래스를 제외한 중괄호 {가 나올 때 생성된다. 그리고 매개변수를 할당할 공간을 해당 스택 프레임 안에 할당한다.
    만약 메소드안에서 다른 메소드를 실행해야 할 때는 새로운 스택 프레임을 생성하게 되고,
    if같은 제어문이 나타났을 때는 해당 스택 프레임 안에 새로운 스택 프레임을 생성한다.
    }가 나오면 메소드가 종료됨과 동시에 스택 프레임도 사라진다.
    만약 main() 스택 프레임이라면 프로그램이 종료된다.
    내부 스택프레임에서 외부 스택프레임에 접근은 가능하지만, 그 역은 불가능하다.

    변수

    지역 변수 : 스택 영역에서 생성되고 스택 프레임이 사라지면 같이 사라진다.
    클래스 멤버 변수 : 스태틱 영역에 자리잡고 JVM이 종료될 때 까지 static 상태를 유지한다.
    객체 멤버 변수 : 힙 영역에 위치하고, 객체 멤버 변수들은 객체와 함께 가비지 컬렉터라는 메모리 회수기에 의해 제거된다.

    Call By Value

    예를 들어 다음과 같은 코드가 있을 때

    public class Example {
        public void main() {
            int a = 10;
            method(a);
            System.out.println(a); // 10
        }
    
        public void method(int a) {
            a = 20;
        }
    }

    method(a) 에서 a = 20으로 값을 변경해주었지만 main()에서 출력한 a의 값은 여전히 10이다.
    왜냐하면 자바는 메소드를 호출할 때, 매개변수의 주소가 아닌 복사한 값을 넘겨주기 때문이다. 이것을 Call By Value라고 부른다.

    메소드의 블랙박스화 : 위와 같은 예제처럼 메소드안에서 메소드를 호출할 때, 서로 매개값과 반환값만 메소드 사이에서 전달될 뿐, 내부의 지역변수는 알 수 없다. 이것을 블랙박스화 라고 한다.

    멀티 스레드와 멀티 프로세스의 이해

    멀티 스레드는 T자 메모리 구조에서 스택 영역을 스레드 개수만큼 분할해서 쓰는 것이다.
    하나의 스레드에서 다른 스레드의 스택 영역을 참조할 수는 없지만, 스태틱과 힙 영역은 공유한다. 그래서 멀티 프로세스 대비 메모리 사용량이 적다.

    멀티 프로세스는 다수의 T자 메모리 구조를 갖는 것이다.
    멀티 프로세스는 각자의 고유한 영역을 가지는 것이고, 각 프로세스가 서로 참조할 수 없는 만큼 안전한 구조이다. 그러나 메모리 사용량이 크다.

    멀티 스레드에서 static 변수의 사용 문제점

    멀티 스레드는 스태틱 영역을 공유하기 때문에 static 변수를 사용했을 때 생기는 문제가 있다. (Start6.java 참고)
    여러 스레드가 한가지 변수에 동시에 접근하여 값을 바꾸면, 어떤 스레드에서는 원하는 값을 얻지 못하는 경우가 발생한다.
    그래서 static 변수는 피할수 있다면 피하되, 읽기 전용인 경우는 적극 사용한다.

    댓글

Designed by Tistory.