Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- 백엔드 부트캠프
- 패스트캠퍼스
- 오픈패스
- UXUI챌린지
- UXUIPrimary
- 오픈챌린지
- mysql
- KDT
- UXUI기초정복
- 국비지원
- 객체지향
- 국비지원교육
- 오블완
- 디자인교육
- 환급챌린지
- 내일배움캠프
- baekjoon
- 디자인챌린지
- 티스토리챌린지
- Be
- 백엔드
- Java
- 국비지원취업
- 부트캠프
- 백엔드개발자
- 백준
- Spring
- OPENPATH
- 디자인강의
- 내일배움카드
Archives
- Today
- Total
군만두의 IT 공부 일지
[스터디6] 02. 자바와 절차적/구조적 프로그래밍 본문
목차
02. 자바와 절차적/구조적 프로그래밍
- 자바: 객체지향 언어이면서 근본적으로는 프로그래밍 언어
1. 자바 프로그램의 개발과 구동
자바 개발 환경을 이해하려면 JVM(Java Virtual Machine)의 존재와 역할을 아는 것이 필수다.
현실 세계 | 가상 세계(자바 월드) | |
소프트웨어 개발 도구 | JDK - 자바 개발 도구 | JVM용 소프트웨어 개발 도구 |
운영체제 | JRE - 자바 실행 환경 | JVM용 OS |
하드웨어 - 물리적 컴퓨터 | JVM - 자바 가상 기계 | 가상의 컴퓨터 |
▲ 현실 세계 vs. 가상 세계
- JDK(Java Development Kit): 자바 소스 컴파일러인 javac.exe 포함
- JRE(Java Runtime Environment): 자바 프로그램 실행기인 java.exe 포함
- 자바에서 위와 같은 구조를 택한 이유는 기존 언어로 작성한 프로그램은 각 플랫폼(하드웨어와 OS의 조합)용으로 배포되는 설치 파일을 따로 준비하는 불편함을 없애기 위해서다.
- 자바의 특성: Write Once Run Anywhere
코드 실행 영역 | 데이터 저장 영역 |
▲ 프로그램이 메모리를 사용하는 방식
코드 실행 영역 | 스태틱(Static) 영역 | |
스택(Stack) 영역 | 힙(Heap) 영역 |
▲ 객체 지향 프로그램의 메모리 사용 방식
자바에 존재하는 절차적/구조적 프로그래밍의 유산
- 절차적 프로그래밍을 한마디로 표현하면 goto를 쓰지 말라는 것이다.
- 자바 공식 문서에서 goto와 const는 not used(사용 안 함)로 되어 있다.
- goto를 사용하면 프로그램의 실행 순서가 인간이 이해하기에 너무 복잡해질 가능성이 있다.
- 다른 언어의 const 역할을 자바에서는 final이 대신한다.
abstract | continue | for | new | switch |
assert | default | goto | package | synchronized |
boolean | do | if | private | this |
break | double | implements | protected | throw |
byte | else | import | public | throws |
case | enum | instanceof | return | transient |
catch | extends | int | short | try |
char | final | interface | static | void |
class | finally | long | strictfp | volatile |
const | float | native | super | while |
▲ 자바의 예약어
- 구조적 프로그래밍은 함수를 쓰라는 것이다.
- 중복 코드를 한 곳에 모아 관리할 수 있다.
- 논리를 함수 단위로 분리해서 이해하기 쉬운 코드를 작성할 수 있다.
- 공유 사용 시 문제가 발생하기 쉬운 전역 변수보다는 지역 변수를 써야 한다.
객체지향 언어에서 절차적/구조적 프로그래밍의 유산은 메서드 안에서 확인할 수 있다. 제어문이 존재할 수 있는 유일한 공간이 메서드 내부이기 때문이다.
Q. 함수(Function)와 메서드(Method)는 무엇이 다를까?
A. 함수는 클래스나 객체와 아무 관계가 없지만, 메서드는 반드시 클래스 정의 안에 존재해야 한다.
abstract | continue | for | new | switch |
assert | default | goto | package | synchronized |
boolean | do | if | private | this |
break | double | implements | protected | throw |
byte | else | import | public | throws |
case | enum | instanceof | return | transient |
catch | extends | int | short | try |
char | final | interface | static | void |
class | finally | long | strictfp | volatile |
const | float | native | super | while |
▲ 자바에 존재하는 절차적/구조적 프로그래밍의 유산
다시 보는 main() 메서드: 메서드 스택 프레임
- main() 메서드: 프로그램이 실행되는 시작점
public class Start {
public static void main(String[] args) {
System.out.println("Hello OOP!!!");
}
}
스태틱 영역 - 클래스들의 놀이터 | |
스택 영역 - 메서드들의 놀이터 | 힙 영역 - 객체들의 놀이터 |
▲ T 메모리 구조
- main() 메서드가 실행되기 전 JVM에서 수행하는 전처리 작업들
- java.lang 패키지를 T 메모리의 스태틱 영역에 배치한다.
- import된 패키지를 T 메모리의 스태틱 영역에 배치한다.
- 프로그램 상의 모든 클래스 T 메모리의 스태틱 영역에 배치한다.
- 이제 System.out.println("Hello OOP!!!") 구문을 실행하게 될까?
- 스택 프레임(stack)이 스택 영역에 할당된다.
- 메서드의 인자 args를 저장할 변수 공간을 스택 프레임의 맨 밑에 할당한다.
- T 메모리를 구성하고 나면 main() 메서드 안의 첫 명령문을 실행하게 된다.
- System.out.println("Hello OOP!!!") 구문이 실행되면
- T 메모리에는 변화가 없다.
핵심 내용 정리
- T 메모리 구조
- java.lang 패키지
- import 패키지와 클래스들
- 메서드 스택 프레임
- JVM
- JRE
힙 영역은 중요한 영역이지만 2장에서는 다루지 않는다.
2. 변수와 메모리: 변수! 너 어디 있니?
public class Start2 {
public static void main(String[] args) {
int i;
i = 10;
double d = 20.0;
}
}
- main() 메서드 스택 안에 밑에서부터 변수 i를 위한 공간을 마련할 때, 현재 변수 i에 저장된 값은 알 수 없는 값이다.
- 선언만 하고 10으로 초기화하지 않으면, i 변수를 사용하는 코드에서 자바 컴파일러(javac)는 오류를 발생시킨다.
- 닫는 중괄호로 main() 메서드 스택 프레임이 스택 영역에서 사라진다. (프로그램 종료)
3. 블록 구문과 메모리: 블록 스택 프레임
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는 조건에 따라 분기를 일으킬 것이다.
- 여는 중괄호를 만나면 스택 프레임이 시작된다고 했는데, 여기서 만들어지는 스택 프레임은 메서드의 스택 프레임이 아니라 if문, 참인 블록의 스택 프레임이다.
- if 블록 중 참일 때의 블록을 종료하는 닫는 중괄호를 만나면 if 블록 스택 프레임은 스택 영역에서 사라진다.
- main() 메서드 스택 프레임을 소멸시키는 블록 마침 기호인 닫는 중괄호를 만나면 T 메모리 소멸, JVM 기동 중지, JRE가 사용했던 시스템 자원을 운영체제에 반납하게 된다.
4. 지역 변수와 메모리: 스택 프레임에 갇혔어요!
Q. T 메모리는 세 개의 영역이 있는데 변수는 스태틱 영역, 스택 영역, 힙 영역 중 어디에 있는 걸까?
A. 세 군데에 모두
- 지역 변수:
- 스택 영역에서, 그것도 스택 프레임 안에서 일생을 보낸다.
- 스택 프레임이 사라지면 함께 사라진다.
- 클래스 멤버 변수:
- 스태틱 영역에서 일생을 보낸다.
- JVM이 종료될 때까지 고정된(static) 상태로 그 자리를 지킨다.
- 객체 멤버 변수:
- 힙에서 일생을 보낸다.
- 객체와 함께 가비지 컬렉터라고 하는 힙 메모리 회수기에 의해 일생을 마친다.
외부 스택 프레임에서 내부 스택 프레임의 변수에 접근하는 것은 불가능하나 그 역은 가능하다. → if 블록 스택 프레임 예
5. 메서드 호출과 메모리: 메서드 스택 프레임 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;
}
}
- square() 메서드를 호출하면 제어 흐림이 square() 메서드가 선언된 줄로 이동할 것이다.
- 메서드 호출이 일어나면 메서드의 스택 프레임이 T 메모리 스택 영역에 새로 생성된다.
- square() 메서드 스택 프레임에는 반환값을 저장할 변수 공간이 맨 아래, 인자를 저장할 변수 공간, 메서드의 지역 변수가 자리 잡는다.
- square() 메서드 안의 k 변수에 무슨 짓을 해도 main() 메서드 안의 k 변수는 영향이 없다.
- main() 메서드가 가진 변수 k와 square() 메서드가 가진 변수 k는 이름만 같고 서로 별도의 변수 공간이다.
- Call By Value(값에 의한 호출)
- result 변수에 25라는 값이 저장디고, 호출한 쪽에 돌려줄 값을 가져야 할 반환값 변수에 result 변수에 담긴 값이 복사될 것이다.
- 닫는 중괄호를 만나면 square() 메서드 스택 프레임은 스택에서 사라진다. 반환값이 있으니 그 값을 돌려주면서 사라진다.
- 닫는 중활호를 만나면 스택 프레임 하나가 또 사라지면서 main() 메서드 스택 프레임을 메모리에서 사라지게 하고, 모든 프로그램이 종료된다.
Q. main() 메서드의 어디에선가 square() 메서드 내의 지역 변수 result에 직접 접근할 수 있을까? 반대로 square() 메서드의 어디에선가 main() 메서드의 지역 변수 m에 직접 접근할 수 있을까?
A. 절대 접근할 수 없다.
6. 전역 변수와 메모리: 전역 변수 쓰지 말라니까요!
두 메서드 사이에 값을 전달하는 방법
- 메서드를 호출할 때 메서드의 인자를 이용하는 방법
- 메서드를 종료할 때 반환값을 넘겨주는 방법
- 전역 변수를 사용하는 방법
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 변수는 T 메모리의 스태틱 영역에 변수 공간이 할당된다.
- main() 메서드 스택 프레임에 k 변수 공간이 만들어진다.
- fun() 메서드 스택 프레임이 생성되고 인자값들과 반환값을 저장할 변수 공간도 생긴다.
- 메서드 밖에서 선언된 변수 share는 메서드들 사이에서 공유해서 사용할 수 있는 전역 변수가 된다.
지역 변수와 전역 변수의 특징
- 스택 프레임에 종속적인 지역 변수
- 스택 프레임에 독립적인 전역 변수
전역 변수를 쓰지 말라고 하는 이유
- 프로젝트 규모에 따라 코드가 커지면서 여러 메서드에서 전역 변수의 값을 변경하기 시작하면, T 메모리로 추적하지 않는 이상 전역 변수에 저장되어 있는 값을 파악하기 쉽지 않다.
- 읽기 전용으로 값을 공유해서 전역 상수로 쓰는 것은 좋다.
7. 멀티 스레드 / 멀티 프로세스의 이해
- 멀티 스레드(Multi Thread)의 T 메모리 모델: 스택 영역을 스레드 개수만큼 분할해서 쓰는 것
스태틱 영역 | ||
스택 영역 - 메서드들의 놀이터 | 힙 영역 | |
스레드 | 스레드 |
▲ 멀티 스레드는 스택 영역을 스레드 개수만큼 분할해서 사용
- 멀티 프로세스(Multi Process): 다수의 데이터 저장 영역, 즉 다수의 T 메모리를 갖는 구조
- 장점: 하나의 프로세스가 다른 프로세스의 T 메모리 영역을 절대 침범할 수 없는 메모리 안전한 구조이다.
- 단점: 메모리 사용량은 크다.
- 멀티 스레드:
- 하나의 T 메모리 안에서 스택 영역만 분할한 것이기 때문에, 하나의 스레드에서 다른 스레드의 스택 영역에는 접근할 수 없다.
- 스태틱 영역과 힙 영역은 공유해서 사용하는 구조다.
이 글은 『스프링 입문을 위한 자바 객체 지향의 원리와 이해』 책을 학습한 내용을 정리한 것입니다.
'프로그래밍 > 객체지향' 카테고리의 다른 글
[스터디6] 04. 자바가 확장한 객체 지향 (0) | 2025.03.22 |
---|---|
[스터디6] 03. 자바와 객체지향 (0) | 2025.03.15 |
[스터디6] 01. 사람을 사랑한 기술 (0) | 2025.03.01 |
[스터디2] 11. 테스트와 설계 (0) | 2025.02.22 |
[스터디5] 01. 협력하는 객체들의 공동체, 이상한 나라의 객체 (0) | 2025.02.20 |
Comments