참고자료

인프런 자바 프로그래밍 입문 강좌 ,

오라클 Java Language Specification ,

https://docs.oracle.com/javase/specs/jvms/se12/html/jvms-2.html

그 외 블로그..

https://minwan1.github.io/2018/06/06/2018-06-06-Java,JVM/

https://sehun-kim.github.io/sehun/JVM/


 

객체지향프로그래밍(Object Oriented Programing)

객체끼리 상호작용하는 프로그래밍 방법. JAVA, C++...

 

객체(Object)

포괄적 의미: 속성을 가진 모든 것. 사람(키,혈액형,이름 등의 속성이 있음),과자(당도,모양 등의 속성이 있음)

프로그램 관점: 객체를 데이터화 해서 실제 메모리에 올린 것

 

클래스(Class)

객체를 어떻게 데이터화 시킬건지 정의하는 설계도

속성 정의(어떤 값을 가짐), 메소드 정의(어떤 동작을 수행)

 

->즉, 객체지향프로그래밍은 

클래스에서 객체를 뽑아내서 그 객체들을 이용해서 어떤 동작을 수행하는 프로그램을 만드는 것이다.

Car라는 클래스에서 포르쉐,아우디,벤츠라는 객체가 만들어지면 3대의 자동차가 레이싱을 하는 프로그램을 만들 수 있다.

 

->장

클래스와 패키지로 구분되기 때문에 잘 만들어진 설계도를 가져와서

내가 원하는 기능을 추가해서 쓸 수 있다. 혹은 설계도를 나눠서 만들 수 있어서 협업이 편하다.

더보기

내 경험:

->단

설계도를 재사용을 하기 때문에 설계시 많은 고민이 필요하다.

객체를 많이 만들면 처리하는 속도가 느려진다.

더보기

내 경험:


JAVA 동작 과정

 

 

"개발자"가 자바 코드를 작성하고 코드 파일을 저장한다. 이때, 자바 코드 파일의 확장자는 .java이다.

"자바 컴파일러"는 .java파일을 .class파일로 만든다. (이 시기를 컴파일 타임이라고 한다)

더보기

클래스 파일로 만든다는 것은 바이트 코드로 만든다는 것이다.

바이트 코드란? JVM이 읽을 수 있는 코드를 뜻한다. cpu가 0110101과 같은 이진코드를 읽을 수 있듯이 cpu역할을 하는 jvm은 아래와 같이 생긴 바이트 코드를 읽을 수 있다.

jvm이 바이트코드를 읽는 것은 자바의 독립성과 관련이 있다. 이 페이지 하단에서 설명할 것!

"jvm"은 .class파일을 읽어서 코드가 나타내는 동작을 수행한다. (이 시기를 런타임이라고 한다)

 

이때, JVM이 동작하기 위해선 JRE가 있어야하고 JRE는 JDK에 포함되어 있다.

이게 무슨 말이냐?? 꽤 중요한 부분이니 집중하자!!

 

 

JVM(Java Virtual Machine):

자바가상머신, cpu칩과 같은 역할을 하는 소프트웨어 칩이다. cpu칩이 기계어 코드를 읽는다면 JVM은 바이트 코드를 읽는다. 클래스 파일을 실행시킬 때 동작하기 때문에 런타임의 엔진에 속한다.

JAVA와 OS사이에서 바이트 코드를 기계어로 변환시켜준다. 

이 말은 즉, JAVA는 이식성이 좋다는 것을 의미한다. 

어떤 OS에서 한번 클래스파일을 만들고 나면, 다른 OS에서 별다른 수정없이

클래스파일을 실행시켰을 때 동일한 결과가 나오기 때문이다.

 그래서 JAVA는 OS에 독립적이고, JVM은 종속적이라고 할 수 있다.

또 JVM에 포함되는 GC(가비지 컬렉터)는 힙의 메모리를 알아서 관리해준다.

C언어 같은 경우 메모리를 할당한 뒤 사용이 끝나면 직접 해제를 해줘야 하는데

JAVA는 GC가 존재하기 때문에 메모리를 효율적으로 관리할 수 있다.

그래서 JAVA와 C의 가장 큰 차이를 꼽는다면, JVM의 유무라고 할 수 있다.

 

JRE(Java Runtime Environment):

JVM과 JVM이 동작할때 필요로 하는 파일들을 포함한다. 이름 그대로 컴파일타임이 아닌

런타임의 환경이므로 소스파일이 아닌 클래스파일일때 작동한다.

 

JDK(Java Development Kit):

JRE와 javac.exe 등을 포함한다.

자바로 프로그램을 개발하는데 필요한 것을 모아둔 키트이다. 

소스파일에서 클래스파일이 되기까지의 과정을 가능하게 해주므로

컴파일타임을 위해서 javac(자바컴파일러)를 포함하는 것에 주의하자.

 

 

모두 Oracle사이트에서 다운로드 받을 수 있다.

+여담이지만, 자바를 제임스 고슬링이 썬이란 기업에서 발명했고 썬은 오라클에 인수되어

현재 오라클이 자바 업데이트를 관리하고 있다. 일반적으로 java로 개발을 하려면 jdk를 설치하면 된다.

현재 jdk최신 버전은 12이며 8이 가장 안정화되어 있다.

목적에 따라 SE(개인용),EE(기업용),ME(임베디드용)로 나뉘어져 있는데 처음 시작한다면 SE를 설치하면 된다.

 

+필요에 따라 jdk를 설치하지 않을수도 있다.

가령, 이클립스 툴을 통해 Java 어플리케이션을 개발한다면 jdk가 필요하다.

하지만, Tomcat 웹서버를 구동하기 위해서는 jre만 필요하다.

Tomcat은 사용자 입장에서 Class 파일만 구동시킬 수 있으면 그만이기 때문이다.


cmd에서 메모장으로 자바 코딩

*파란색 글씨는 입력해야하는 명령어입니다*

*jvm이 설치되어 있고 환경변수까지 설정되어 있어야 합니다*

 

 

0. cmd창에서 파일을 저장할 위치로 이동한다. (cd+ 해당 위치)

더보기

정말정말 초보를 위해서.. 위치를 알아내는 법! 동그라미 친 부분을 클릭하면 경로 복사가 가능하다

C:\~~에 뭐가 더 붙었을 것이다..현재 위치가 바뀌었다는 말! 이젠 메모장 실행 (notepad)

 

1. 메모장에서 프로그램이 수행할 동작을 JAVA 문법을 사용한 코드로 작성하고

파일 이름은 Test.java로 저장한다 (클래스이름+확장자 .java)

 

2. 지금 위치에 코드 파일이 잘 저장되었는지 확인 (dir)

 

3.자바 컴파일러를 불러와서 컴파일 해준다. (javac + java파일이름.java)

4. 2번과 마찬가지로 확인해보면 기존의 java파일과 새로 생성된 class파일이 있다.

5.class파일을 jvm으로 실행시킨다. (java + class파일이름)

!!주의할 점!!

4번에선 파라미터의 이름이 Test.java이지만 5번에선 Test이다.

5번에서 확장자를 적으면 에러가 발생한다.

이유는 나의 추측이지만,class파일로 만들면서 이미 문법의 유효성이나 확장자로 파일 내용의 유효성 검사를 마쳤고,

실행만 하면 되기 때문 아닐까싶다.

 

이 모든 과정을 우리는 시꺼먼 cmd 대신 이클립스라는 보편적이고 깔끔한 IDE로 진행할 수 있다.

IDE에서 코드를 작성하면 javac와 같은 명령어는 입력하지 않아도 된다.

ctrl+s가 javac역할을 하고

run버튼이 java역할을 하기 때문이다.

 


JVM 동작 과정

 

위 그림의 큰 사각형에 포함되는 부분을 JVM 아키텍처라고 부른다.

JVM은 Class Loader,Runtime Data Areas,Execution으로 구성된다.

 

1. 컴파일러가 소스코드를 컴파일해서 클래스파일로 만들고 난 뒤, 클래스파일을 실행한다.

-JVM 동작 시작-

2. 클래스로더가 바이트코드를 Runtime Data Area에 로딩한다.

3.4.3.4..바이트코드는 Execution 엔진에 의해 해석된 후 해석된 코드는 Runtime Data Areas의 각 영역의 목적에 맞게 배치되며 실질적인 수행이 이루어진다. 

 

 

 

Runtime Data Areas

 

프로그램이 실행될 때 JVM이 운영체제로부터 할당받는 메모리 영역이다. 

생성 시기에 따라 분류하면 다음과 같다.

 

1.쓰레드가 시작될 때마다 생성(쓰레드마다 할당받는 메모리)

PC Resiter

여러 쓰레드들은 자신이 현재 실행중인 메소드의 주소를 저장하고 있다.

 

JVM Stack(

스택프레임(메소드 단위)으로 push(메소드 시작) pop(메소드 종료) 연산을 수행한다. 

각 '스택프레임'은 'Local Variable Array 지역변수배열'와 'Operand Stack 피연산자 스택'의 참조값을 저장한다. 이 값들은 컴파일시에 크기가 결정 되었으므로 JVM스택의 크기는 쓰레드가 실행되는 초기에 고정된다. 그러므로 이 크기를 넘는 경우 Stack Overflow가 발생할 수 있다. 

이 과정에서 JVM스택은 힙과 함께 동작한다.

 

Local Variable Array:

0은 this 주소

1부터 매개변수

그 뒤는 지역변수

 

Operand Stack:

메소드의 실제 작업공간. Local Variable Array와 데이터를 교환한다. 다른 메서드 호출 결과를 push pop한다.

 

Native Method Stack

C/C++ 코드를 수행하기 위한 스택이다.

 

2.모든 쓰레드가 공유

Method Area,Runtime Constatnt Pool

JVM이 시작될 때 각 클래스의 구조를 텍스트(바이트코드)로 저장하는 영역이다.(컴파일때 크기가 정해져서 크기 고정)

Rutime Constant Pool,필드 코드, 메소드 코드를 포함한다.

특히 Runtime Constant Pool에선 모든 메서드,인터페이스의 실제 주소를 가지고 있다. 

이 영역에 있는 클래스 정보로 Heap 영역에 객체를 생성한다.  

 

 

Heap

런타임에 할당되는 영역이며, 모든 클래스와 배열의 객체가 저장되는 곳이다. GC(따로 포스팅) 의 대상이며 동기화 처리가 일어나는 영역이다. GC에 의해 자동적으로 버릴 메모리를 관리하며 정해진 힙의 크기를 넘어가면 OutOfMemoryError가 발생한다. 

 

 

 

 

  • JRE가 자바프로그램을 실행시킬 때 맨처음으로 main()를 찾는다.
  • 있으면 Class Loader가 목적파일(.class)을 실행시킴
  • static 영역에 java.lang 패키지, import한 패키지들을 위치시킨다. 프로그램에 있는 모든 클래스와 필드 ,메소드가 올라감
  • stack영역에 main()의 Stack Frame이 위치하고 변수 영역에 인자를 위치시킨다.
    • 지역변수의 경우 선언이 아닌 초기화 될 때 위치된다.
    • 클래스 선언 {}을 제외하고 메소드의 {}, if의 {}이 생길때 마다 Stack Frame이 생긴다.
  • 메소드를 실행
  • ”}”괄호를 만나게 되면 Stack Frame이 사라진다.
  • JRE는 JVM을 종료시키고 위치했던 메모리들이 모두 없어진다.

 

 

 

 

 

Execution Engine

Runtime Data Areas에 배치된 바이트코드를 명령어 단위로 읽어서 실행한다.

그 방식은 Interpreter, JIT 두 가지가 있다.(다른 포스팅) 

 

 

 

 

+ Recent posts