이번 장에서는 프로그래밍언어로서의 자바를 공부해보자.
객체지향과 스프링으로 나아가기 위한 사전지식을 점검해보자.
개발자는 JDK를 통해서 소스파일을 만들고 , 자바 컴파일러에 의해 자바 목적파일을 만든다.
이런 목적파일은 각각의 플랫폼에 깔린 자바 실행환경인 JRE내에 있는 JVM에서 자바 바이트코드를 해당 플랫폼에서 실행 가능한 기계어로 해석하고 실행한다.
🧑💻 개발자 : JVM에서 돌아갈 수 있는 JVM용 프로그램을 작성하고 배포
⚙️ JVM : 실행은 각 플랫폼의 JVM가 해결해준다.
다만 배포의 편리성을 위해 JDK내에 JRE가 JRE내에 JVM가 포함된 형태로 배포된다.
자바는 절차적 프로그래밍과 구조적 프로그래밍 이후에 나와 각각의 유산을 가지고 있다고 한다.
절차적 프로그래밍과 구조적 프로그래밍도 아주 널은 내용이지만, 자바에 포함되어 있는 부분만 짧게 공부해보자.
자바의 절차적 프로그래밍 유산
goto
를 쓰지마라!
자바의 구조적 프로그래밍 유산
➡️ 메서드 : Method
main()
메서드를 실행하기 위한 자바public class Start {
public static void main(String[] args) {
System.out.println("Hello. OOP!!");
}
}
👉 화면에 해당 문자열이 나오는 간단한 코드지만, 자바는 이를 위해서 열심히 으쌰으쌰한다!!
java.lang
을 스태틱 영역에 놓는다.(📌 중괄호마다 하나씩 스택 프레임이 생성된다고 생각해보자.)
args
를 놓기 위한 변수공간을 스택 프레임 영역내 변수공간을 할당한다.📌 중요했던 개념
⭐ T 메모리 구조
⭐ java.lang 패키지
⭐ import 패키지와 클래스들
⭐ 메서드 스택 프레임
⭐ JVM와 JRE
T 메모리 구조 - 스태틱(Static) 영역, 스택(Stack) 영역, 힙(Heap) 영역을 말한다.
(사실 이 부분은 공부를 하면서 계속 나오는 부분이다. 포스팅도 추가적으로 했었다.ㅎ..)
스태틱 | 클래스 |
---|---|
스택 | 메서드 |
힙 | 객체 |
/*
1. 모든 자바프로그램에 포함된 “java.lang”을 스태틱 영역에 놓는다.
2. 프로그램 상의 모든 클래스를 T 메모리의 스태틱 영역에 배치한다.
*/
public class Start2 {
//스택 영영엑 메서드 당 스택 프레임을 만들어준다.
public static void main(String[] args) {
// 스택 프레임 내에 변수 저장 영역을 부여한다.
int i;
i = 10;
// 스택 프레임내에 변수 저장 영역을 부여한다.
double d = 20.0;
}
}
/*
1. 모든 자바프로그램에 포함된 “java.lang”을 스태틱 영역에 놓는다.
2. 프로그램 상의 모든 클래스를 T 메모리의 스태틱 영역에 배치한다.
*/
public class Start3 {
// main메서드의 스택 프레임을 스택영역에 할당한다.
public static void main(String[] args) {
// 각각의 변수를 할당한다.
int i = 10;
int k = 20;
// 괄호로 만들어지는 블록의 스택프레임을 main 스택 프레임내에 할당한다.
if (i == 10) {
int m = k + 5;
k = m;
} else {
int p = k + 10;
k = p;
}
//할당한 스택 프레임을 종료한다.
//따라서 스택프레임내에 있던 변수 m은 종료된다.
}
}
/*
1. 모든 자바프로그램에 포함된 “java.lang”을 스태틱 영역에 놓는다.
2. 프로그램 상의 모든 클래스를 T 메모리의 스태틱 영역에 배치한다.
*/
public class Start4 {
//main 메서드용 스택 프레임을 스택영역에 할당한다.
public static void main(String[] args) {
// main 스택 프레임 영역에 변수를 할당
int k = 5;
int m;
// 메서드의 인자와 반환값을 사용해 변수값을 공유
m = square(k);
}
// square 메서드용 스택 프레임을 스택영역에 할당한다.
private static int square(int k) {
// square 스택 프레임 영역에 변수를 할당한다.
int result;
k = 25;
result = k;
return result;
}
}
/*
1. 모든 자바프로그램에 포함된 “java.lang”을 스태틱 영역에 놓는다.
2. 프로그램 상의 모든 클래스를 T 메모리의 스태틱 영역에 배치한다.
*/
public class Start5 {
// 스태틱 영영엑 share변수 저장 영역을 만든다.
// 스태틱 변수는 어디에서나 공유된다.
static int share;
// 스택 영역에 main 메서드용 스택 프레임을 만든다.
public static void main(String[] args) {
share = 55;
//fun메서드를 실행한다.
int k = fun(5,7);
//종료한다.
System.out.println(share);
}
// 스태틱 영역에 fun용 스택 프레임을 할당한다.
private static int fun(int m, int p) {
share = m + p;
return m-p;
}
}
🤔 전역변수를 쓰지말라고?
전역변수의 값을 추적하기 어렵기 때문이다.
하나의 T 메모리만 사용하고 스택영역을 분할해서 사용한다.
스태틱 영역과 힙영역은 공유해서 사용한다.
따라서 멀티 프로세스 대비 메모리를 적게 사용할 수 있는 구조이다.
각각의 프로세스마다 각자의 T 메모리를 가지고 있기 때문에 서로 참조할 수 없다.
하나의 프로세스가 다른 프로세스의 T 메모리 영역을 절대 침범할 수 없는 메모리가 안전한 구조이다.
메모리 사용량은 크다.
🤔 서블릿은 요청당 프로세스가 아닌 요청당 스레드를 생성한다.
- 요청 당 스레드를 제공하는 서블릿이 CGI보다 더 효율적이다.
- 요청당 프로세스를 제공하는 CGI
전역변수를 공유하기 대문에 충돌하고 예상할 수 없는 문제가 발생한다.
🤮 보완하는 방법인 lock
이 있지만, 이를 사용하면 멀티스레드의 장점은 버라는 것이다 ~
public class Start6 extends Thread {
static int share;
public static void main(String[] args) {
Start6 t1 = new Start6();
Start6 t2 = new Start6();
t1.start();
t2.start();
}
public void run() {
for (int count = 0; count < 10; count++) {
System.out.println(share++);
try {
sleep(1000);
} catch (InterruptedException e) {
}
}
}
}
으으 복잡해~