Java 개발 환경 구축

byeol·2023년 3월 30일
0

Write Once, Run Anywhere(WORA; 한국어: 작성은 한 번만, 돌리는 건 어디서든)은 1995년에 썬 마이크로시스템즈가 만든 자바의 표어이다. 이는 컴퓨터에 따라 다른 코드를 작성해야 했던 어셈블리어와 다르게 자바는 컴퓨터가 달라도 하나의 통일된 코드로 실행할 수 있다는 장점을 나타내기 위해 제작되었다. 현대에는 자바뿐만 아니라 대부분의 프로그래밍 언어가 이를 일부분에서 모두 지원한다.

자바의 표어를 기억하면서 어떻게 저게 가능할까라는 의문을 가지며 읽으면 좋을거 같습니다.


큰 그림부터 그려보면

JDK ⊃ JRE ⊃ JVM
이런 포함관계를 갖는다는 것을 기억하고 정리해보려고 합니다.

JVM(Java Virtual Machine)

JVM은 자바를 실행하기 위한 가상 기계입니다.
JVM의 등장으로 개발자는

  • 일종의 에뮬레이터이기 때문에 자바 프로그램이 어느 기기, 또는 어느 운영체제 상에서도 실행될 수 있다는 것입니다.

    .java➡️자바 컴파일러➡️.class(Java bytecode)➡️JVM : OS가 이해할 수 있도록 해석➡️OS

  • 메모리를 개발자가 직접 관리하지 않아도 됩니다.

    JVM은 가바지 컬렉션을 통해 불필요한 메모리를 알아서 정리해줍니다. (C언어를 이용하면 free()라는 함수를 통해서 직접 메모리를 해체해야 합니다.) 즉 동적할당을 프로그래머에게 맡기지 않고 JVM에서 전적으로 맡고 스스로 수행합니다.

JVM 구조

JVM은 위와 같이 구성되어져 있는데 하나씩 살펴봅시다.

1. Class Loader

바이트 코드로 작성된 class파일을 JVM내로 로드하는 역할을 합니다.
class들은 Runtime Data Area에 배치됩니다.

2. Execution Engine

Class Loader에 의해 메모리엑 적재된 클래스의 Bytecode들을 기계어로 변경하고 명령어 단위로 실행합니다.
명령어 실행 방식

  • JIT : 정적 컴파일 방식 + 인터프리터 방식 혼합, 실행 시점에서 인터프리트 방식으로 기계어 코드를 생성함과 동시 그 코드를 캐싱
  • 인터프리트 방식 : 실행 중 프로그래밍 언어를 한줄 씩 읽어가면서 해당 기능에 대응하는 기계어 코드를 실행

3. Garbage Collector

Heap 메모리 영역에 생성된 객체들 중에 참조되지 않는 객체들을 탐색 후에 제거하는 역할

JVM의 Heap 영역은 처음에 설계될 때 2가지의 전제로 설계되었다고 합니다.

  • 대부분의 객체는 금방 접근 불가능한 상태가 된다.

  • 오래된 객체에서 새로운 객체로의 참조는 아주 적게 존재한다.

    (Perm 영역은 Java8 이후부터 제거되었습니다.)
    따라서 객체의 생존기간에 따라 Heap 영역을 Young,Old 2가지로 나누게 되었습니다. 여기서 참조 변수의 개념을 알고가야 합니다. 참조 변수는 객체의 주소가 저장된 변수입니다. 참조 변수는 Stack 영역에 있습니다. 참조변수가 null이 된다면 Heap 영역에 있는 객체는 Unreachable한 상태가 되었다고 표현됩니다. Unreachabel한 객체는 필요없기 때문에 사라지는데 사라지게 만드는 역할을 가비지 컬렉터가 합니다. 다시 돌아와서 Young 영역과 Old영역의 기준을 살펴봅시다.

  • Young 영역

    • 새롭게 생성된 객체가 할당되는 영역
    • 대부분의 객체가 금방 Unreachable 상태가 되기 때문에 많은 객체가 Young 영역에 생성되었다가 사라집니다.
    • Young 영역에 대한 가비지 컬렉션을 Minor GC라고 부릅니다.
  • Old 영역

    • Young 영역에서 Reachable 상태를 유지하여 살아남은 객체가 복사되는 영역

    • Young 영역보다 크게 할당되며, 영역의 크기가 큰 만큼 가비지는 적게 발생합니다.

    • Old 영역에 대한 가비지 컬력션을 Mojor GC 또는 Full GC라고 부릅니다.

    Young 영역에 있는 객체를 참조하는 객체가 Old 영역에 존재할 수도 있습니다. 따라서 Young영역에 Minor GC가 실행될 때 Old 영역이 참조하고 있는지 확인을 해야 합니다. 처음부터 끝까지 Old 영역 모두를 확인하는 것이 비효율적이기 때문에 카드 테이블을 조회하여 참조하고 있는지 확인합니다.
    즉 카드 테이블에는 Old 영역에 있는 객체가 Young 영역의 객체를 참조할 때마다 그에 대한 정보가 표시됩니다.

4. Runtime Data Area

메모리의 구조를 생각해봅시다. 프로그램이 실행되기 위해서 먼저 프로그램이 메모리에 로드되어야 합니다. 운영체제로 할당받는 대표적인 메모리 공간을 떠올려보면 각자 어떤 역할을 하는지 더 자세히 눈에 들어옵니다.

    1. Class Area(=Method Area)
    • Code Area=Static Area=Method Area
    • 클래스정보(멤버변수의 이름), 변수정보(데이터타입, 접근제어자정보), 메소드정보(메소드 이름, 리턴타입, 파라미터, 접근제어자 정보),static 변수, final class 변수, 상수풀이 저장됩니다.
    • JVM이 동작해서 클래스가 로딩될 때 생성
    1. HeapArea
    • new 키워드로 생성된 객체와 배열이 저장되는 영역(참조변수가 저장되는 것이 아닙니다. 참조변수가 가리키는 객체가 저장됩니다!)
    • Method Area에 로드된 클래스만 생성이 가능합니다.
    • GC의 주요 대상이 됩니다.(Stack, class Area도 대당)
    • 효율적인 GC를 위해 메모리 영역이 분리되어 있습니다.
    • 모든 스레드가 공유하는 영역입니다.
    • 런타임시 할당됩니다.
    1. Stack Area
    • 메서드가 호출되면 수행에 필요한 만큼의 메모리가 스택에 할당 받습니다.
    • 참조형 변수는 객체의 힙영역의 객체의 주소값을 가지고 힙영역의 객체를 가리킵니다.
    • 지역변수, 파라미터, 리턴값, 연산에 사용되는 임시값 등이 생성되는 영역입니다.
    • 메소드를 호출할 때마다 개별적으로 스택이 생성되며 종료 시 영역에서 해체됩니다.
    • 컴파일 타임시 할당됩니다.
    1. PC Register
    • 스레드가 생성될 때마다 생성되는 영역으로 현재 스레드가 실행되는 부분의 주소와 명령을 저장하고 있습니다.
    1. Native method stack
    • 자바 외 언어로 작성한 네이티브 코드를 위한 메모리입니다.

JVM 프로세스와 멀티 스레드

실제로 어떻게 메모리가 사용되는지 살펴봅시다.


JVM은 하나의 프로세스입니다. 프로세는 실행중인 프로그램을 프로세스라고 하는데요.

위 그림을 보면 Main Thread가 있습니다,
이는 우리가 코드를 짤 때 사용하는 main()메서드입니다.

하지만 프로그램을 만들때 하나의 Thread만을 이용할 수도 있고 여러 개의 Thread를 사용할 수도 있습니다.

Java 언어로 만들어진 대표적인 프로그램인
톰캣(Web Application Server)의 경우 여러 개의 Thread를 지원하여 사용자의 요청마다 별도의 Thread를 만듭니다. 그러나 요청마다 새로운 Thread를 만드는 것은 비효율적입니다. 왜냐하면 다음 사용자가 사용할 수도 있는데 버리고 다시 만드는 비용이 발생하기 때문입니다. 그래서 Thread Pool을 이용하여 개수를 정해 미리 그 개수만큼 만들어두고 이를 계속 재사용하는 것입니다. 그 개수를 개발자가 정하며 최대 200개까지 정할 수 있습니다.

여러 개의 Thread를 이용하는 멀티쓰레드의 경우 위와 같이 Heap영역과 Method영역을 공유합니다. Heap 영역에는 new 연산자로 생성된 객체가 저장되는데 Thread끼리는 이를 공유하기 때문에 Thread에서 이 값을 변경하지 않도록 주의해야 합니다.

JRE(Java Runtime Environment)

JRE는 자바 클래스 라이브러리, 자바가상머신(JVM), 자바 클래스 로더를 포함하고 있습니다.
클래스 로더와 클래스 라이브러리를 통해 작성한 자바 코드를 라이브러리와 결합한 후 JVM에 넘겨 실행시킵니다. JRE는 그 자체로 특별한 기능을 한다기 보다는 JVM이 원활하게 잘 작동할 수 있도록 환경을 맞춰주는 역할을 합니다.

JDK(Java Development Kit)

JDK(Java Develpment Kit)는 자발 개발 키트라는 말로 자바 애플리케이션을 구축하기 위한 핵심 플랫폼 구성요소입니다. 그 중심에는 자바 컴파일러가 있다고 합니다.

JDK를 설치하면 JRE,JVM이 자동으로 설치됩니다.

JDK의 설치

오라클 JDK 다운로드 링크

위 링크를 통해 JDK를 설치했다면 개발자는 Java를 통해 개발할 수 있는 모든 환경이 구축되었습니다.

이제 실제로 JDK를 이용하여 cmd창에서 compile을 진행해보려고 합니다.
제가 작성한 아래의 글을 참고하셔서 환경변수를 설정과 cmd로 컴파일을 진행해보시면 됩니다.

cmd(커맨드 라인)으로 컴파일하기

컴파일 이후
클래스 파일들과 외부 라이브러리들을 연결하는 링킹의 작업과 연결된 클래스 및 리소스 파일 묶어주는 패키징, 그리고 기능을 테스트해야 하는 나머지 작업들이 있습니다.

결국 개발자는 컴파일->링킹->패키징->테스트의 과정을 모두 수동으로 해야하며 이 과정을 통해서 하나의 프로그램을 만들 수 있습니다.

이를 빌드라고 합니다.

JDK 설치 후 자동으로 Build 해주는 Buill Tool로 실행파일 만들기

gradle 설치

reference

https://mangkyu.tistory.com/118
https://d2.naver.com/helloworld/1329
https://hyoje420.tistory.com/2
https://m.blog.naver.com/goreng2/221770110714
https://kotlinworld.com/38
https://kimvampa.tistory.com/27
https://velog.io/@kmdngmn/Windows-cmd%EC%97%90%EC%84%9C-%ED%8F%B4%EB%8D%94%EB%A5%BC-jar%ED%8C%8C%EC%9D%BC-%EC%83%9D%EC%84%B1%ED%95%98%EA%B8%B0

Update

2023.06.03 JVM 프로세스와 멀티 스레드와 JDK의 설치~끝까지 Update

profile
꾸준하게 Ready, Set, Go!

0개의 댓글

관련 채용 정보