Link Search Menu Expand Document

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

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

  • 현실 세계 vs. 가상 세계 | 현실 세계 | 가상 세계(자바 월드) | | |–|–|–| | 소프트웨어 개발 도구 | JDK - 자바 개발 도구 | JVM용 소프트웨어 개발 도구 | | 운영체제 | JRE - 자바 실행 환경 | JVM용 OS | | 하드웨어 - 물리적 컴퓨터 | JVM - 자바 가상 기계 | 가상의 컴퓨터 |

    • JDK는 자바 소스 컴파일러인 javac.exe를 포함
    • JRE는 자바 프로그램 실행기인 java.exe를 포함
    • Write Once Run Anywhere
  • 객체 지향 프로그램의 메모리 사용 방식

객체 지향 프로그램의 메모리 사용 방식

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

  • 절차적 프로그래밍: goto를 쓰지 말 것. 자바는 goto를 사용하지 못하도록 예약어로 등록함
  • 구조적 프로그래밍: 함수 사용 권장
    • 중복 코드를 한 곳에 모아 관리
    • 논리를 함수 단위로 분해하여 이해하기 쉬운 코드 작성
    • 공유 사용 시 문제가 발생하기 쉬운 전역 변수보다는 지역 변수 사용 권장
  • 함수(Function)와 메서드(Method)의 차이
    • 절차적/구조적 프로그래밍에서는 함수, 객체 지향에서는 메서드
    • 메서드는 반드시 클래스 정의 안에 존재해야 함
    • import 문은 단순한 편의 기능
  • 자바의 예약어 중 절반 이상(continue, for, switch, default, goto, boolean 등)이 절차적/구조적 프로그래밍의 유산

다시 보는 main() 메서드: 메서드 스택 프레임

public class Start {
	public static void main(String[] args) {
  	System.out.println("Hello OOP!!!");
  }
}
  • JRE는 프로그램 안에 main() 메서드가 있는지 확인
  • main() 메서드가 확인되면 JRE는 JVM을 부팅, JVM은 전처리 시작
  • java.lang 패키지를 T 메모리의 스태틱 영역에 배치
  • 개발자가 작성한 모든 클래스와 임포트 패키지를 스태틱 영역에 배치
  • 여는 중괄호를 만날 때마다 스택 프레임이 스택 영역에 할당됨
  • 메서드의 인자 args를 저장할 변수 공간을 스택 프레임의 맨 밑에 배치
  • 구문 실행은 T 메모리 바깥에서 일어나므로 구문 실행 시 T 메모리에는 변화가 없음
  • 닫는 중괄호를 만날 때마다 스택 프레임이 소멸됨
  • main() 메서드가 종료되면 JRE는 JVM을 종료, JRE도 운영체제 메모리에서 제거됨

변수와 메모리: 변수! 너 어디 있니?

public class Start2 {
	public static void main(String[] args) {
  	int i;
    i = 10;

    double d = 20.0;
  }
}
  • 변수 idmain() 메서드 스택 프레임 내에 저장됨
  • 선언만 하고 초기화되지 않은 변수를 사용할 경우 자바 컴파일러(javac)는 경고 메시지를 보냄

블록과 메모리: 블록 스택 프레임

public class Start3 {
	public static void main(String[] args) {
  	int i = 10;
    int k = 20;

    if(i == 10) {
    	int m = k + 5;
      k = m;
    } else {
    	int p = k + 10;
      k = p;
    }

    //k = m + p;
  }
}
  • if를 만날 경우 main() 스택 프레임 내에 새로운 스택 프레임이 중첩되어 생성됨
  • 변수 m은 새로운 스택 프레임 내부에 존재하고 if 문의 닫는 중괄호를 만날 때 소멸됨
  • 주석을 해제할 경우 변수 mp는 T 메모리 내에 존재하지 않으므로 컴파일 오류가 발생함

지역 변수와 메모리: 스택 프레임에 갇혔어요!

  • 지역 변수: 스택 영역에 존재, 스택 프레임이 사라지면 함께 사라짐
  • 클래스 멤버 변수: 스태틱 영역에 존재, JVM이 종료될 때까지 존재
  • 객체 멤버 변수: 힙에 존재, 가비지 컬렉터에 의해 회수될 때까지 존재
  • 외부 스택 프레임에서 내부 스택 프레임의 변수에 접근하는 것은 불가능하나 그 역은 가능

메서드 호출과 메모리: 메서드 스택 프레임 2

public class Start4 {
	public static void main(String[] args) {
  	int k = 5;
    int m;

    m = square(k);
  }

  private static int square(int k) {
  	int result;
    k = 25;

    result = k;

    return result;
  }
}
  • 메서드 호출이 일어나면 무조건 호출되는 메서드의 스택 프레임이 T 메모리 스택 영역에 새로 생성됨
  • main() 메서드 내에서는 square() 메서드 내에 존재하는 지역변수에 접근할 수 없음
  • 자바에서는 포인터를 사용할 수 없으므로 메서드 스택 프레임 사이에 변수를 참조할 수 없음
  • 메서드를 호출하면서 인자로 전달되는 것은 변수 자체가 아니라 변수가 저장한 값 (Call by Value)

전역 변수와 메모리: 전역 변수 쓰지 말라니까요!

public class Start5 {
	static int share;

  public static void main(String[] args) {
  	share = 55;
    int k = fun(5, 7);

    System.out.println(share);
  }

  private static int fun(int m, int p) {
  	share = m + p;

    return m - p;
  }
}
  • share 변수는 static 키워드가 붙어 있으므로 T 메모리의 스태틱 영역에 저장되는 전역 변수
  • 전역 변수는 여러 메서드에서 변경할 수 있으므로 저장되어 있는 값을 파악하기 어려움
  • 전역 변수는 읽기 전용으로 값을 공유하는 상수로 사용하는 것이 좋음

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

  • 멀티 스레드: T 메모리의 스택 영역을 스레드 개수만큼 분할해서 사용
    • 하나의 스레드에서 다른 스레드의 스택 영역에는 접근할 수 없지만 스태틱 영역과 힙 영역은 공유
  • 멀티 프로세스: 다수의 T 메모리를 가짐
    • 각 프로세스의 T 메모리는 고유의 공간이므로 프로세스끼리 참조할 수 없음
  • 멀티 프로세스는 멀티 스레드에 비해 메모리 사용량이 커짐
  • 요청당 스레드(Servlet)가 요청당 프로세스(CGI)보다 효율적
  • 스태틱 영역에 있는 쓰기 가능한 전역 변수를 스레드가 사용할 경우 스레드 안정성이 깨짐