[Java] Java 기초

박채은·2022년 10월 31일
0

Java

목록 보기
6/30

Java 탄생 배경

자바가 탄생하기 이전에는 C++이 많이 사용되고 있었다. C++는 C 언어를 기반으로 한 객체 지향 언어로, 운영체제에 독립적이지 못한 단점을 갖고 있었다. 즉, 운영체제 별로 프로그램을 만들고 컴파일 해줘야 했다.

이런 문제점을 해결하고자 만든 것이 Java이다.
Java는 객체 지향 언어이면서, 운영체제에 독립적이다.
이런 독립성은 JVM을 통해서 만들어진다.

Java의 특징

Java는 "Write Once, Run Anywhere"라는 슬로건을 내세운 "객체 지향 프로그래밍 언어"이다.

1. 운영체제에 독립적
자바 이전의 언어들은 특정 CPU에서만 작동하거나 특정 OS에 따라 다르게 작성해야 하는(C, C++) 언어들이 대부분이었다.
자바는 JVM이 설치되어 있는 모든 운영체제에서 실행이 가능하다.

2. 객체 지향 언어(OOP)
Java는 객체 지향 언어(Object Oriented Programming)이다.
모든 기능은 객체로 만들어 사용되며, 객체 지향적으로 설계된 프로그램은 유지보수가 쉽고 확장성이 높다.

3. 함수형 프로그래밍 지원
Java 8 버전 부터 람다식과 스트림이 추가되어 코드가 간결해졌다.

4. 자동 메모리 관리(Garbage Collection)
Java는 가비지 컬렉터가 있어, 사용하지 않는 메모리를 자동으로 수거해준다.
메모리를 관리하는 수고를 덜 수 있다.


JDK/JRE/JVM

JVM

  • Java Virtual Machine(자바 가상 머신)
    • 가상 머신: 프로그램을 실행하기 위해 물리적 머신과 유사한 머신을 소프트웨어로 구현한 것
  • 자바 프로그램을 실행시키는 도구
    • 자바 프로그램이 어느 기기, 어느 운영체제 상에서도 실행될 수 있게 만들어준다.(WORA)
    • Java와 운영체제 사이의 중재자 역할
  • 자바는 JVM을 거치기 때문에 C나 C++에 비해 속도는 느린 편
    (JVM 내부의 최적화된 JIT 컴파일러를 통해 속도가 크게 개선되긴 했다.)
  • 가비지 컬렉션을 수행한다.

JVM 구성

  • Class Loader(클래스 로더)
    • JVM 내로 클래스를 로드하고, 링크를 통해 배치하는 작업을 수행하는 모듈
    • Runtime 시에 Loading을 통해 JVM 내로 컴파일된 바이트 코드(.class)를 동적 로딩하고, Linking을 통해 라이브러리 클래스를 배치하는 작업을 한다.
  • Execution Engine(실행 엔진) : 클래스를 실행시킨다. 바이트코드를 기계어로 변환하는데 이때 변환하는 방법은 2가지가 있다.
    1. Interpreter(인터프리터)
      • 자바 바이트 코드를 명령어 단위(한 줄)로 읽어서 실행한다.
      • 한 줄씩 실행하기 때문에 느리다는 단점이 있다.
    2. JIT compiler
      • 인터프리터의 단점을 보완하기 위해 도입된 방법
      • 바이트 코드 전체를 컴파일하여 기계어로 변환한다.
  • Garbage collector: 힙 영역에 사용되지 않는 객체들을 제거하는 작업
  • Runtime Data Area: 프로그램을 실행하기 위해서 OS에게 할당받은 메모리

코드의 실행 과정

1) 소스 코드(.java)를 컴파일러(javac)가 컴파일한다.
2) JVM은 컴파일된 바이트코드(.class)를 각 운영체제에 맞는 기계어로 변한다.

프로그램이 실행되기 위해서는 운영체제에게 자원(cpu, 메모리, I/O 등)을 할당받아야 한다. 따라서 프로그램이 필요한 자원을 운영체제에게 요청하고, 운영체제가 이 요청을 받아들여 프로그램에게 자원을 할당해준다.

이때 프로그램이 자원을 요청하는 방식이 운영체제마다 다르고, 이것 때문에 운영체제에 종속성을 가지게 되는 것이다.(운영체제에 맞게 프로그래밍 해줘야 한다.)

하지만 자바는 JVM이 있기 때문에 운영체제에 독립적일 수 있다. JVM은 자바 코드로 작성된 프로그램을 운영체제에 맞게 실행시키기 때문이다.

자바는 JVM을 통해서 운영체제와 소통한다.
즉, JVM은 자바 프로그램(애플리케이션)과 운영체제의 통역가 역할을 하는 것이다.

JVM은 여러 버전이 있고(Window 버전 JVM, Mac 버전 JVM 등), 각각의 버전들이 본인의 운영체제에 맞게 프로그램을 변환해준다.
즉, JVM으로 인해서 운영체제로부터 독립적일 수 있다.

JRE

  • Java Runtime Environment
  • 자바 실행 환경(자바 코드를 실행하기 위한 도구들로 구성된 패키지)
  • JVM + 표준 클래스 라이브러리

JDK

  • Java Development Kit
  • 자바 개발 도구
  • JRE + 개발에 필요한 도구
  • JDK를 설치하면 JRE, JVM이 자동으로 다 설치됨
    ex) OpenJDK, OracleJDK

[참고]
https://m.blog.naver.com/goreng2/221770110714
http://asfirstalways.tistory.com/158


자바 프로그램 실행 과정

컴파일: 개발자가 만든 소스 코드를 컴퓨터가 이해할 수 있도록 0과 1로 구성된 바이너리 언어로 파일로 바꾸어 주는 것

  1. 개발자가 자바 소스코드(.java)를 작성
  2. 자바 컴파일러(javac)가 자바 소스코드(.java)를 읽어 바이트 코드(.class)로 컴파일한다. (이때의 바이트 코드는 컴퓨터는 읽을 수 없고, JVM만이 이해할 수 있는 코드이다.)
  3. JVM은 운영 체제로부터 코드 실행에 필요한 메모리(런타임 데이터 영역)를 할당받는다.
  4. 컴파일된 바이트 코드를 JVM의 클래스 로더로 전달
  5. JVM의 클래스 로더동적 로딩을 통해 바이트 코드(.class)를 JVM의 메모리(런타임 데이터 영역)에 올린다.
  6. 로드가 완료되면, JVM의 실행 엔진(Execution Engine)이 메모리에 적재된 코드를 실행한다.
    6-1) 인터프리터(Interpreter)를 통해 코드를 한 줄씩 기계어로 번역하고 실행한다.
    6-2) JIT Compiler를 통해 바이트 코드 전체를 기계어로 번역하고 실행한다.

평소엔 인터프리터(6-1)로 실행하다가, 특정 코드가 자주 반복되면 해당 코드를 JIT Compiler(6-2)를 통해 실행시킨다. JIT 컴파일러로 인해서 효율성이 향상된다.

참고-1
참고-2
참고-3


런타임 데이터 영역

이전에 작성해둔 [Java] 객체지향 프로그래밍 기초 글 참고!


가비지 컬렉션

  • 메모리를 자동으로 관리해주는 기법
    • 힙 영역에서 사용하지 않은 객체들을 제거해주는 작업
    • 프로그램이 동적으로 할당했던 메모리 중에서 필요없게 된 객체(참조가 끊긴 상태)를 찾아 삭제하여 메모리를 확보
  • 개발자가 직접 메모리를 해제해줄 필요가 없기 때문에 효율적으로 메모리를 사용 가능

Minor GC/Major GC

힙 영역에 저장되는 객체들은 대부분 일회성이고, 저장되어 있는 시간은 짧다.
그래서 얼마나 살아있느냐에 따라 Young, Old 영역으로 나눈다.

[이미지 출처]
http://asfirstalways.tistory.com/158

  • Minor GC: Young 영역에서 발생
  • Major GC: Old 영역에서 발생
  • Young 영역: 많은 객체가 빨리 생성되었다가, 빨리 사라짐
  • Old 영역
    • 상태를 유지하고 살아남은 객체들이 복사되는 곳
    • 가비지는 적게 발생한다.

동작 방식

  1. Stop the world
    • 가비지 컬렉션을 실행하기 위해서, JVM이 애플리케이션의 실행을 멈춤
    • 모든 스레드의 작업은 중단되고, 가비지 컬렉션이 완료된 후에 다시 재개된다.
  1. Mark and Sweep
    • Mark: 사용되는 메모리와 사용되지 않는 메모리를 식별하는 작업
    • Sweep: Mark 단계에서 사용되지 않는다고 식별된 메모리를 해제하는 작업

즉, 모든 스레드를 중단시키고, 사용되는 메모리와 사용되지 않는 메모리를 식별하여 사용되지 않는 메모리는 해제해준다.

📌 가비지 컬렉션에 대한 자세한 설명

0개의 댓글