이미지 출처:https://velog.io/@ghkdwp018/JAR-vs.-WAR

 

 

java jvm환경에서 애플리케이션을 개발할 때 애플리케이션을 쉽게 배포하고 동작시킬 수 있도록 관련파일(리소스, 속성파일 등)들을 패키징 해주는 jar, war에 대하여 알아보자

 


 

JAR(Java Archive)

여러 개의 Java 클래스 파일, 메타데이터, 리소스 파일 등을 하나의 파일로 묶은 아카이브 파일로

Java 클래스와 관련 리소스를 패키징하여 재사용 가능한 라이브러리나 실행 가능한 애플리케이션을 생성한다.

사용처는 Java 라이브러리, standalone(독립실행) Java 애플리케이션, 의존성 패키지

JAR파일은 플랫폼에 귀속되는 점만 제외하면 WIN ZIP파일과 동일한 구조이다.

** standalone 방식은 스프링 부트만 실행하면 자동으로 서블릿 컨테이너까지 설정하고, 실행해 준다는 의미

 

 

Java 애플리케이션 실행방식에 대한 장단점

 

1. Standalone 애플리케이션

 

장점

  • 독립적으로 실행가능하고 사용자에게 쉽게 배포할 수 있다.
  • GUI(Graphical User Interface)또는 CLI(Command-Line Interface) 기반으로 직관적으로 사용가능하다.

단점

  • 시스템에 따라 환경설정이 필요할 수 있다.
  • 여러 사요 자가 동시에 접근하기 어렵다.

 

2. 웹 애플리케이션

 

장점

  • 여러 사용자가 동시에 접근이 가능하다.
  • 클라이언트 - 서버 아키텍처로 중앙 집중식 관리 가 용이하다.

단점

  • 서버 및 클라이언트 간 네트워크 의존성
  • 서버 유지보수 및 보안 문제가 있을 수 있음.

 

3. 모듈형 애플리케이션

 

장점

  • 모듈화로 인해 유지보수와 확장이 용이함.
  • 필요한 모듈만 로드하여 성능 최적화 가능.

단점

  • 복잡한 아키텍처로 인해 학습 곡선이 가파를 수 있음.
  • 종속성 관리가 어려울 수 있음

 

4. 컨테이너화된 방식

 

장점

  • 일관된 실행환경 제공, 배포가 간편함.
  • 종속성 문제를 줄이고, 확장성이 뛰어남.

단점

  • 컨테이너 관리 및 오케스트레이션의 복잡성,
  • 초기설정이 복잡할 수 있음.

 

WAR(Web Application Arcshive)

웹 애플리케이션을 패키징 하기 위한 파일포맷으로 Java 클래스, JSP, 서블릿, XML, 라이브러리, 정적웹리소스(HTML, CSS, JavaScript)등 웹 애플리케이션 구성요소 포함하며 하나의 단위로 패키징하고 배포하기 위한 목적으로 사용

사용처는 Java 기반의 웹 애플리케이션 서버나 서블릿 컨테이너(Tomcat, JBoss, WebLogic 등)에서 실행되는 웹애플리케이션에 사용

 

**서블릿(Servlet)
Servlet은 자바 기반의 웹 애플리케이션을 개발하기 위한 서버 측 프로그램 또는 기술이다.
서블릿은 HTTP 요청(Request)을 받아 이를 처리한 뒤 HTTP 응답(Response)을 생성하여 클라이언트에게 전달하는, 다시 말하면 클라이언트의 요청을 처리하여 동적인 웹 페이지를 생성하는 역할

**서블릿 컨테이너(Servlet Container)
서블릿은 혼자서 동작할 수 없기 때문에 서블릿을 실행하고 관리해 주는 서블릿 컨테이너 내에서 동작한다.
서블릿 컨테이너는 서블릿 객체를 생성, 초기화, 호출, 종료하는 생명주기를 관리할 뿐만 아니라, 클라이언트의 요청을 받고 응답할 수 있도록 웹 서버와의 소켓 통신을 지원한다.

 

웹사이트 배포순서

 

1. 웹사이트의 파일과 리소스를 준비한다.

    HTML, CSS, JavaScript 등으로 이루어짐

 

2. 웹 호스팅 서비스 또는 웹서버를 준비한다.

   GitHub Pages AWS 등이 웹호스팅 Apache, Microsoft IIS 등 웹서버

 

3. 웹사이트 업로드 웹 호스팅 사이트나 웹서버에 파일을 업로드한다.

 

4. 도메인 등록

    도메인을 구매하고 DNS 설정을 통하여 웹호스팅 또는 웹서버의 IP를 등록한다.

 

5. 배포 전 검증

     웹사이트가 실제 배포환경에서 제대로 동작할지 사전에 확인하는 과정으로 다양한 테스트와 점검이 이루 진다.

 

 - 코드리뷰: 개발된 코드가 모범사례에 따라 작성되었는지, 효율적인지, 유지보수가 용이한지, 보안문제, 성능저하요소 불필요한 코드 등이 있는지 검토

- CI/CD 파이프라인에서 자동화된 테스트

단위테스트: 각 함수나 메서드가 의도한 대로 동작하는지 개별적으로 테스트

통합테스트: 여러 모듈이 통합되어 정상적으로 상호작용하는지 확인

UI 테스트: 사용자의 실제 워크플로우에 따라 전체 시스템이 제대로 동작하는지 시나리오 기반으로 확인

End-to-End(E2E) 테스트: 사용자의 실제 워크플로우에 따라 전체 시스템이 제대로 동작하는지 시나리오 기반 확인

- 스테이징 환경에서 검증

스테이징 환경은 실제 배포 환경과 유사한 환경에서 웹사이트를 실행하여, 배포 후 발생할 수 있는 문제를 사전에 파악

배포할 코드가 실제 서버에서 제대로 동작하는지 확인할 수 있는 환경 데이터베이스, 외부 API, 서버 성능 등도 검증

 - 성능테스트

부하 테스트: 사용자가 급증할 때 웹사이트가 얼마나 잘 대응할 수 있는지 확인

응답시간테스트: 페이지 로드 시간, API 응답시간 등을 테스트하여 성능이 기준을 충족하는지 확인

 - 보안 검증

취약점스캐닝: OWASP Top 10 같은 일반적인 보안 취약점(SQL 인젝션, xss 등)에 대한 자동화된 도구를 활용한 스캔

인증 및 권한 테스트: 사용자 권한 및 접근 제어가 올바르게 설정되어 있는지 확인

HTTPS 검증: 사이트가 HTTPS를 통해 안전하게 제공되고 있는지 확인

 - 환경설정 검증

배포할 환경(서버, 데이터베이스, 클라우드 서비스 등)이 올바르게 설정되어 있는지 확인

서버 자원(메모리, CPU) 및 설정 파일들이 제대로 구성되었는지 검증

 

[결과]

JAR은 JAVA애플리케이션이 동작할 수 있도록 자바프로젝트를 압축한 파일

WAR은 웹어플이 케이션 압축파일 포맷으로 웹 관련 자원만 포함하고 있으며 이를 사용하면 웹 애플리케이션을 쉽게 배포가능 WAR파일을 실행하려면 Tomca, Weblog, Websphere 등의 웹서버나 웹컨테이너가 필요하다

 

[느낀 점]

war, jar 업무 하면서 어디선가 보았던 파일들이었는데 이번 공부를 하면서 무슨 파일인지 알아보았다 

JAR이나 WAR파일로 압축한다는 개념이라면 압축을 풀 수도 있을지 찾아봐야겠다.

 

 

 

 

 

 

https://sharonprogress.tistory.com/225

 

Jar 파일과 War 파일이란? 차이점도!

웹 프로그래밍을 공부하면서 질리게 듣게 되는 파일 형식이다. JAR 파일과 WAR 파일은 둘 다 Java 기반의 애플리케이션을 패키징하기 위한 파일 포맷이다. 1. Jar(Java ARchive)파일 정의: JAR 파일은 여러

sharonprogress.tistory.com

https://ifuwanna.tistory.com/224

 

[Java] JAR WAR 차이점 및 특징 ( + EAR )

JAR (Java Archive) WAR (Web Application Archive) 모두 JAVA의 jar 툴을 이용하여 생성된 압축(아카이브) 파일이며 어플리케이션을 쉽게 배포하고 동작시킬 수 있도록 있도록 관련 파일(리소스, 속성파일 등)들

ifuwanna.tistory.com

 

https://wildeveloperetrain.tistory.com/372

 

서블릿과 서블릿 컨테이너 이해하기(Servlet, ServletContainer)

서블릿과 서블릿 컨테이너 이해하기(Servlet, ServletContainer)서블릿(Servlet)과 서블릿 컨테이너(ServletContainer)는 자바 기반 웹 애플리케이션을 개발하는데 기본이 되고 또 자주 만나게 되는 개념입니

wildeveloperetrain.tistory.com

 

 

 

 

java는 다양한 버전이 존재한다 그중 많이 쓰이는 버전은 java 8, 11, 17이 세 가지 버전이 많이 쓰이는 이유는 LTS(Long Term Support) 버전으로 LTS버전이란 장기간 보안업데이트와 버그 수정을 지원해 주는 버전이다.

 

JET BRAINS에 웹페이지에서 2021년도 2022년도 사용 통계를 확인

 


 

1. java8

  • 오라클이 자바 인수 후 출시한 첫 번째 LTS 버전
  • 32bit를 지원하는 마지막 공식 Java 버전
  • Oracle JDK(Oracle사에서 지원하는 버전으로 유료) , Open JDK(오픈소스 기반의 무료)로 나뉨
  • 새로운 날짜와 시간 API(LocalDateTime 등)
  • 람다식(Lambda), Stream API
  • PermGen 영역 삭제
  • Static Link JNI Library

 

람다식(Lambda)

함수를 간단한 식으로 표현하는 방법이다. 메서드 이름과 반환값이 생략되서 익명함수(anonymous function)이라고도 불림

int max(int a, int b) {
    return a > b ? a : b;
}

//람다식으로 변환
(a, b) -> a > b ? a : b;

 

Stream API

컬렉션의 저장 요소를 하나씩 순회하면서 처리할 수 있는 코드패턴으로 람다식을 지원하고 내부 반복자를 사용하기 때문에 병렬 처리가 쉽다는 특징이 있음

List<String> lowercase = Arrays.asList("a", "b", "c", "d", "e");
lowercase.stream()
        .map(String::toUpperCase)
        .forEach(System.out::println);

 

interface default method

java 8 이전의 인터페이스는 메서드 정의만 할 수 있고 구현 할 수  없었지만 8 버전부터는 default method라는 개념이 생기면서 구현 내용도 인터페이스에 포함시킬 수 있게

public interface TestInterface {
    void doSomething();
    default void doSomethingDefault() {
        System.out.println("doing something default");
    }
}

//implements the interface
public class TestClass implements TestInterface {
    @Override
    public void doSomething() {
        System.out.println("doing something");
    }
}

TestClass testClass = new TestClass();
testClass.doSomething();          // Output: "doing something"
testClass.doSomethingDefault();   // Output: "doing something default"

 

optional class

optional<T>는 nul이 올 수 있는 값을 감싸는 Wrapper 클래스로 참조하더라도 NPE(Null Pointer Exception)가 발생ㅈ하지 않도록 도와주는 역할을 한다 따라서 예상치 못한 NPE(Null Pointer Exception)이 발생될 상황에서도 예시와 같이 제공되는 메서드를 통해 간단히 예외 처리 가능

//create an optional that contains a value
Optional<String> optional = Optional.of("Hello, world!");
//check if a value is present
if (optional.isPresent()) {
	String value = optional.get();
	System.out.println(value);    // Output: "Hello, world!"
}
		
//create an empty optional
Optional<String> emptyOptional = Optional.empty();
//get a default value if the optional is empty
String value = emptyOptional.orElse("default value");
System.out.println(value);    // Output: "default value"
		
//throw exception
emptyOptional.orElseThrow(() -> new RuntimeException("throw Exception"));

 

2. java 11

  • Oracle JDK와 Open JDK 통합되고 Oracle JDK가 구독형 유료 모델로 전환
  • 람다 지역 변수 사용 방법 변경
  • Third Party JDK로의 이전 필요
  • HTTP 클라이언트 표준화 기능
  • 앱실론 가비지 컬렉터 (Epsilon GC)

 

람다 지역변수 사용 방법 변경

var 키워드는 java 10에서 추가 var 키워드를 사용하는 경우 데이터 유형을 지정하지 않고 변수를 선언하고 정의할 수 있으며 컴파일러는 할당된 데이터 유형에 따라 데[이터 유형을 결정하게 

(var s1, var s2) -> s1 + s2

 

HTTP Client

11 버전에서 도입된 Java HttpClient API는 최신 HTTP 표준의 클라이언트를 구현하고 동기 및 비동기 프로그래밍 모델인 HTTP/1.1 및 HTTP/2를 지원한다

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://test-api.com/posts"))
        .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

 

3. java 17

  • 봉인 클래스(Seald Class) 정식 추가
  • 패턴 매칭 프리뷰 단계
  • Incubator (Foreign Function & Memory API)
  • 애플 M1 및 이후 프로세서 탑재 제품군에 대한 정식 지원
  • 의사난수 생성기를 통해 예측하기 어려운 난수를 생성하는 API 추가
  • 컨텐츠 기반의 역직렬화 필터링
  • Record Data Class 추가
  • Spring Boot 3.0부터는 자바 17 이상을 지원 

 

Seald Class

17 버전에서 추가된 Seald Class, Interface는 상속하거나(extends), 구현(implements)할 클래스를 지정해 두고, 해당 클래스들만 상속 또는 구현을 허용하는 키워드
개발자는 seald 키워드를 통해 어떤 클래스가 해당 클래스를 상속 또는 구현하는지를 쉽게 알 수 있고, 또 제한할 수 있다.

public sealed class Shape permits Circle, Square {
    // common fields and methods
}

public final class Circle extends Shape {
    // circle-specific fields and methods
}

public final class Square extends Shape {
    // square-specific fields and methods
}

 

Record Data Class

Record 클래스는 불변 데이터를 객체 간에 전달하는 작업을 간단하게 만들어주며 record를 사용함으로 불필요한 코드를 제거할 수 있고 적은 코드로 명확한 의도(data carrier)를 표현할 수 있다.

//Lombok 사용 예시
@EqualsAndHashCode
@ToString
@AllArgsConstructor
@Getter
public class Person {
    private final String name;
    private final String address;
}

//record class 예시
public record Person (String name, String address) { }

 

텍스트 블록(Text Blocks)

멀티라인의 문자열을 이스케이프 시퀸스 없이 사용하여 소스코드 작성을 편리하게 하고 코드의 가독성을 높이는데 주된 목적을 지님

String html1 = "<html>\n" +
        "           <body>\n" +
        "               <p>Hello, world</p>\n" +
        "           </body>\n" +
        "       </html>\n";

// Text Blocks
String html2 = """
        <html>
            <body>
                <p>Hello, world</p>
            </body>
        </html>
        """;

 

 

[결과]

자바의 버전별 사용량을 보았을 때 LTS 버전을 주로 사용하고 Spring Boot 3.0부터는 java17 이상을 지원하여 많은 사용자가 java17로 이전

 

[느낀 점]

자바는 하위호환성이 매우 높아서 상위버전에서 하위버전의 기능을 컴파일이 가능하다 java8에서 공부를 하고 상위 버전에 추가된 기능을 공부하는 것이 좋을 것 같다

 

 

 

 

 

참조 사이트

https://wildeveloperetrain.tistory.com/287

 

Java 8, 11, 17 버전별 추가된 기능 (+ 무슨 버전을 써야할까?)

java 8, 11, 17 버전이 많이 사용되는 이유와 버전별 추가된 기능 최근 몇 년 동안 java에서 가장 많이 사용되는 버전은 'java 8'으로 저 역시 실무에서는 java 8만 계속 사용하고 있는데요. 자바는 2021년

wildeveloperetrain.tistory.com

https://code-lab1.tistory.com/253

 

[JAVA] JRE 와 JDK의 차이? Java 8, 11, 17 에 대하여

JRE, JDK란? 처음 Java를 설치하려고 보니 JRE, JDK 등이 존재하는 것을 확인할 수 있다. 둘의 차이는 무엇일까? 참고) [JAVA] 자바(JAVA)란? 자바의 특징 자바(JAVA)란? 자바는 C언어에 객체 지향적 기능을

code-lab1.tistory.com

 

멀티 스레드 환경에서 동시성 문제는 여러 스레드가 동시에 실행되면서 공유자원에 접근하거나 수정할 때 발생하는 문제 동시성 문제는 주로 데이터 불일치, 레이스 컨디션, 데드락 등의 형태로 나타난다.

 

이미지 출처:https://www.javatpoint.com/deadlock-in-java

 

 

 

 

동시성 문제의 유형

  1. 데이터 불일치: 여러 스레드가 동시에 데이터를 읽고 수정하면서 데이터의 일관성이 깨지는 현상.

  2. 레이스 컨디션: 여러 스레드가 경쟁적으로 자원에 접근하면서 발생하는 문제로, 예기치 않은 실행결과가 나올 수 있다.

  3. 데드락: 두 개 이상의 스레드가 서로가 가지고 있는 자원을 기다리면서 무한 대기상태에 빠지는 문제}

Thread-safe 
여러 스레드가 동시에 접근하거나 수정할 수 있는 코드나 객체가
데이터의 일관성과 안정성을 유지하도록 안전하게 설계된 것을 의미한다.

동시성 문제 해결 방법

1. 동기화( Synchronization)

공유자원에 대한 접근을 제어하여 데이터의 일관성을 유지하는 방법으로 Lock을 걸게 되면 스레드의 공유자원에 대한 독점을 허용하기 때문에 다른 스레드가 자원에 접근하지 못하고 대기하게 된다. 이는 여러 스레드가 공유자원에 동시에 접근하지 못하므로 동시성 문제를 막을 수 있지만, 하나의 스레드만 자원을 사용하므로 병렬성은 낮아지게 된다.

public class Counter {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }

    public synchronized int getCount() {
        return count;
    }
}

 

2. Lock 사용

    synchronized키워드를 사용하는 암시적 Lock과는 달리  Lock 객체를 사용하여 더 정교한 제어가 가능

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Counter {
    private int count = 0;
    private final Lock lock = new ReentrantLock();

    public void increment() {
        lock.lock();
        try {
            count++;
        } finally {
            lock.unlock();
        }
    }

    public int getCount() {
        lock.lock();
        try {
            return count;
        } finally {
            lock.unlock();
        }
    }
}

 

3. Atomic 변수 사용

    java.util.concurrent.atomic 패키지의 Atomic 클래스들을 사용하여 스레드 안전하게 값을 수정할 수 있다

Atomic 클래스들은 Compare and Swap(CAS) 기반으로 되어 있어 스레드에 안전하다. Compare and Swap(CAS)란 변수의 값을 변경하기 전에 기존의 값이 내가 예상한 값인지 확인하여 같은 경우에만 값을 할당하는 알고리즘 기법이다. (값을 할당하기 전 한 번 더 검사함) 

import java.util.concurrent.atomic.AtomicInteger;

public class Counter {
    private AtomicInteger count = new AtomicInteger(0);

    public void increment() {
        count.incrementAndGet();
    }

    public int getCount() {
        return count.get();
    }
}

 

4. Concurrent Collections 사용

    java.util.concurrent 패키지는 동시성 문제를 해결하기 위한 다양한 클래스와 인터페이스를 제공한다. ConcurrentHashMap, CopyOnWriteArrayList 등의 클래스들이 있

import java.util.concurrent.ConcurrentHashMap;

public class ConcurrentMapExample {
    private ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();

    public void put(String key, Integer value) {
        map.put(key, value);
    }

    public Integer get(String key) {
        return map.get(key);
    }
}

 

5. 데드락 방지

    잠금 순서를 정해 데드락을 예방하거나, 타임아웃을 설정하여 데드락에 빠지지 않도록 할 수 있다.

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.TimeUnit;

public class DeadlockExample {
    private final Lock lock1 = new ReentrantLock();
    private final Lock lock2 = new ReentrantLock();

    public void method1() {
        try {
            if(lock1.tryLock(10, TimeUnit.SECONDS)) {
                try {
                    if(lock2.tryLock(10, TimeUnit.SECONDS)) {
                        try {
                            // Critical section
                        } finally {
                            lock2.unlock();
                        }
                    }
                } finally {
                    lock1.unlock();
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void method2() {
        try {
            if(lock2.tryLock(10, TimeUnit.SECONDS)) {
                try {
                    if(lock1.tryLock(10, TimeUnit.SECONDS)) {
                        try {
                            // Critical section
                        } finally {
                            lock1.unlock();
                        }
                    }
                } finally {
                    lock2.unlock();
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

 

[결과]

동시성 문제는 주로 데이터 불일치, 레이스 컨디션, 데드락 등의 형태로 나타나고 멀티스레드 환경에서 동시성 문제를 해결하기 위해서는 주로 동기화, Lock 객체, Atomic 변수, Concurrent Collections 등을 사용한다.

 

[느낀 점]

불변객체를 사용하여 동시성 문제를 해결할 수도 있지만 객체를 생성하는 비용이 굉장히 크기 때문에 성능상 문제가 발생할 수 있므로 내용을 제외하였다.

 

 

 

참조 사이트

https://everydayyy.tistory.com/154

 

[Java] 멀티스레드 환경에서의 동시성 문제와 대책

스레드란? 프로세스는 실행중인 프로그램이란 뜻이다. 프로그램이 실제로 실행되어, 메모리나 CPU와 같은 자원을 할당 받으면 이를 프로세스라고 부른다. 스레드는 프로세스 내에서 실제로 작업

everydayyy.tistory.com

 

https://yeoonjae.tistory.com/entry/Java-%EB%A9%80%ED%8B%B0%EC%93%B0%EB%A0%88%EB%93%9C-%EB%8F%99%EA%B8%B0%ED%99%94-synchronized

 

[Java] 멀티쓰레드 동기화 - synchronized

쓰레드의 동기화 씽글쓰레드의 경우에는 하나의 프로세스 내에서 하나의 쓰레드만 작업하기 때문에 프로세스의 자원에 대한 문제가 딱히 없다. 하지만 멀티쓰레드의 경우 여러개의 쓰레드가

yeoonjae.tistory.com

 

이미지 출처:https://medium.com/@wassimdhokkar/difference-between-process-and-thread-90f6c5a5919b

 

프로세스(process)

운영체제로부터 자원을 할당받은 작업의 단위이다. 기본적으로 프로세스당 최소1개의 스레드(메인스레드)를 가지고 있다.

 

주요 특징

  • 독립된 메모리 공간: 각 프로세스는 고유한 주소 공간을 가지고 있어 다른 프로세스와 메모리 공간을 공유하지 않음
  • 자원 소유: 프로세스는 CPU시간, 메모리, 파일핸들 등과 같은 자원을 소유한다
  • 고립성: 한 프로세스의 실패는 다른 프로세스에 영향을 미치지 않는다.
  • 운영체제의 관리: 운영체제는 프로세스의 생성, 실행, 대기, 종료 등을 관리한다.

 

스레드(Thread)

스레드는 프로세스 내에서 실행되는 더 작은 실행 단위.한 프로세스는 여러 스레드를 가질 수 있으며, 이 스레드들은

프로세스의 자원을 공유한다.

 

주요 특징

  • 공유 메모리 공간: 동일한 프로세스 내의 스레드들은 메모리 공간을 공유한다. 이를 통하여 스레드 간의 데이터 공유가빠르고 효율적
  • 독립된 실행 흐름: 각 스레드는 독립적으로 실행흐름을 가지고 있다. 한 스레드가 차단되거나 대기 상태에 있어도 다른스레드는 계속 실행될 수 있다.
  • 경량성: 스레드는 프로세스 보다 생성과 종료에 필요한 자원이 적다.
  • 동기화 문제: 여러 스레드가 동일한 자원에 접근할 수 있으므로 동기화 문제가 발생할 수 있다. 이를 해결하기 위하여뮤텍스, 세마포어 같은 동기화 기법이 사용된다.

 

특징

특징 프로세스 스레드
메모리 공간 독립석인 주소 공간 같은 프로세스 내에서 메모리 공간을 공유
실행단위 독립적인 실행단위 프로세스 내의 독립적인 실행단위
자원 소유 CPU시간, 메모리 등 고유 자원 소유 프로세스의 자원을 공유
생성 및 종료 비용 상대적으로 큼 상대적으로 작음
상호통신 ICP(Inter-Process Communication)필요 메모리 공유를 통해 빠르게 통신가능
독립성 한 프로세스의 실패가 다른 프로세스에 영향없음 한 스레드의 실패가 프로세스의 다른 스레드에 영향

 

멀티프로세스(Multiprocessing)

멀티프로세싱은 여러개의 프로세스를 사용하여 동시에 여러 작업을 수행하는 방식.

 

특징

  • 독립된 메모리 공간: 각 프로세스는 독립된 메모리 공간을 가지며, 다른 프로세스와 메모리 공유하지 않음
  • 높은 안정성: 한 프로세스의 오류가 다른 프로세스에 영향을 미치지 않는다.

장점

  • 안정성: 프로세스 간의 독립성으로 인해 한 프로세스의 오류가 전체 시스템에 영향을 미치지 않는다.
  • 간단한 디버깅: 프로세스가 독립적이므로 디버깅이 비교적 간단하다.

단점

  • 높은 오버헤드: 프로세스 간의 전환이 느리고 더 많은 메모리와 시스템 자원을 소비한다.
  • 복잡한 통신: 프로세스 간 통신이 복잡하고 이를 위해 IPC메커니즘이 필요하다

 

멀티스레드(Multithreading)

멀티스레딩은 하나의 프로세스 내에서 여러 스레드를 사용하여 동시에 여러 작업을 수행하는 방식

 

특징 

  • 공유 메모리: 같은 프로세스 내에서 실행되는 여러 스레드는 메모리와 자원을 공유
  • 효율적인 자원사용: 메모리 및 시스템 자원을 효율적으로 사용한다.

장점

  • 높은 성능: 스레드 간의 통신이 빠르고 효율적이다.
  • 낮은 오버헤드: 스레드 간 전환이 빠르고 자원소모가 적다.
  • 자원 공유: 데이터 공유가 쉽고 효율적이다.

단점

  • 동기화 문제: 자원 공유로 인한 동기화 문제가 발생할 수 있으며, 이를 해결하기 위하여 추가적인 동기화 기법이 필요
  • 안정성: 하나의 스레드 오규가 전체 프로세스에 영향을 미칠 수 있다.

 

 

[결과]

프로세스는 운영체제로부터 자원을 할당받은 작업의 단위이다. 각 프로세스는 고유한 메모리 공간과 자원을 가지고 있다.

스레드는 프로세스 내에서 실행되는 더 작은 단위이다 같은 프로세스 내의 다른 스레드와 메모리 공간을 공유한다.

 

 

[느낀 점]

프로그램은 명령어들의 집합이고 프로세스는 실행 중인 프로그램이다. 프로그램이 메모리에 올라가고 CPU 자원을 할당받은 상태

 

참조사이트

https://velog.io/@hyojhand/OS-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-vs-%EC%8A%A4%EB%A0%88%EB%93%9C

 

[OS] 프로세스 vs 스레드 (Process vs Thread)

프로세스는 각각 독립된 메모리영역 (Code, Data, Stack, Heap 의 구조)을 할당 받는다. 기본적으로 프로세스당 최소 1개의 스레드( 메인 스레드)를 가지고 있다.

velog.io

https://charlezz.medium.com/process%EC%99%80-thread-%EC%9D%B4%EC%95%BC%EA%B8%B0-5b96d0d43e37

 

Process와 Thread 이야기

프로세스(Process)

charlezz.medium.com

 

이미지 출처:https://www.javatpoint.com/exception-handling-in-java

 

 

예외처리

자바의 예외를 try-catch 블록으로 잡았다고 끝이 아니다. 예외가 발생하였으면 코드를 수정하여 문제점을 고쳐야 하는 것이 맞지만 예상할 수 없는 예외의 경우 회피를 하거나 복구 동작을 하는 등 예외를 핸들링하여 처리하는 로직이 필요하다. 예외를 처리하는 방법 예외 복구, 예외 처리 회피, 예외 전환 방법을 알아보자.

 

 

1. 예외복구

  • 예외 상황을 파악하고 문제를 해결해서 정상상태로 돌려놓는 방법
  • Exception이 발생하여도 어플리케이션은 정상적으로 동작
  • 반복문을 이용하여 예외가 발생하더라도 일정 수만큼 재시도를 하여 예외 복구를 시도
  • 만일 최대 재시도 횟수를 넘기게 되는 경우 예외를 발생시키거나 혹은 다른 플랜으로 문제 해결을 시도
  • 네트워크에 연결하거나 하는 등의 로직에서 유용하다.
public class ExceptionRecoveryExample {
    public static void main(String[] args) {
        try {
            int result = divide(10, 0);
            System.out.println("Result: " + result);
        } catch (ArithmeticException e) {
            System.out.println("Error: Division by zero. Trying with a default value.");
            int result = divide(10, 1); // Default recovery logic
            System.out.println("Recovered Result: " + result);
        }
    }

    public static int divide(int a, int b) {
        return a / b;
    }
}

 

2. 예외처리 회피

  • 예외처리를 직접 담당하지 않고 호출한 쪽으로 던져 회피하는 방법(throws)
  • 다만 그렇게 추천되어지는 방법은 아니다.
  • 호출한 쪽에서 예외를 처리하는 것이 바람직할 때 사용한다.
  • 해당 로직에서 예외가 발생했을 때 처리하지 않고 회피하는 것이 최선의 방법일 때만 사용한다.
public class ExceptionPropagationExample {
    public static void main(String[] args) {
        try {
            int result = divide(10, 0);
            System.out.println("Result: " + result);
        } catch (ArithmeticException e) {
            System.out.println("Error: " + e.getMessage());
        }
    }

    public static int divide(int a, int b) throws ArithmeticException {
        if (b == 0) {
            throw new ArithmeticException("Division by zero");
        }
        return a / b;
    }
}

 

3. 예외전환

  • 위의 예외 처리 회피와 비슷하게 메서드 밖으로 예외를 던지지만, 그냥 무작정 던지지 않고 적절한 예외로 필터링해서 넘기는 방법이다.
  • 조금 더 명확안 의미로 전달되기 위해 적합한 의미를 가진 예외로 변경해서 throws 하는 것이라 보면 된다.
  • 이외에도 예외처리를 상위클래스로 단순하게 처리하기 위한 포장(wrap)하는 방법도 일컫는다.
public class ExceptionTranslationExample {
    public static void main(String[] args) {
        try {
            int result = divide(10, 0);
            System.out.println("Result: " + result);
        } catch (CustomException e) {
            System.out.println("Custom Error: " + e.getMessage());
        }
    }

    public static int divide(int a, int b) throws CustomException {
        try {
            return a / b;
        } catch (ArithmeticException e) {
            throw new CustomException("Custom Error: Division by zero occurred", e);
        }
    }
}

class CustomException extends Exception {
    public CustomException(String message, Throwable cause) {
        super(message, cause);
    }
}

 

 

 

 

[결과]

예외복구 방식은 예외 상황을 파악하고 문제를 해결해서 정상상태로 돌려놓는 방법으로 네트워크를 연결하는 방식에서 유용하다.

예외처리 회피방식은 예외처리를 직접담당하지 않고 호출한 쪽으로 던지는 방식으로 해당 로직에서 예외가 발생하였을 때 처리하지 않고 회피하는 것이 최선일 때 사용한다.

예외전환 방식은 예외처리 방식과 비슷하나 메서드 밖으로 예외를 던지지만 적절한 예외로 필터링하여 넘기는 방식이다.

 

[느낀 점]

예외처리방식의 3가지 방식에 대해 알아보았다 프로그램 실행 시 발생할 수 있는 예기치 못한 예외의 발생에 대비한 코드를 작성하는 것으로 프로그래밍의 코드작성에 중요하고 많이 쓰일 것으로 보인다

 

 

 

 

 

 

https://inpa.tistory.com/entry/JAVA-%E2%98%95-Exception-Handling-%EC%98%88%EC%99%B8%EB%A5%BC-%EC%B2%98%EB%A6%AC%ED%95%98%EB%8A%94-3%EA%B0%80%EC%A7%80-%EA%B8%B0%EB%B2%95

 

☕ Exception Handling - 자바 예외를 처리하는 3가지 기법

Exception Handling 3가지 기법 자바의 예외를 try - catch 블럭으로 잡았다고 해서 끝이 아니다. 예외가 발생하였으면 코드를 수정하여 문제점을 고쳐야 되는 것은 맞지만, 예상할 수 없는 예외인 경우

inpa.tistory.com

 

이미지 출처:https://www.itrelease.com/2011/05/difference-between-static-final-and-abstract-class-in-java/

 

추상화란?

java에서의 추상화는 클래스들의 중요하고 공통된 성질들을 추출하여 부모 클래스를 선정하는 개념이다.

java 클래스를 작성하기 위한 설계도를 소스코드 형태로 제시하는 역할을 한다.

 

 

추상 클래스(Abstract Class)

class 앞에 abstract 키워드를 사용하여 정의하며, 하나 이상의 추상 메서드를  가지는 클래스를 말한다. 추상 메서드를 선언하여 상속을 통해서 하위 클래스에서 (반드시) 구현하도록 강제하는 클래스 

  • 추상 클래스는 인스턴스, 즉 객체를 만들 수 없는 클래스(new 키워드로 객체 생성불가)
  • 추상 클래스는 상속키워드 extends를 사용한다.(일반 클래스 상속과 동일)
  • 추상 메서드는(추상 클래스를 상속 받는) 하위 클래스에서 메소드의 구현을 강제해야한다(Override)
  • 추상 메서드를 포함하는 클래스는 반드시 추상 클래스여야 한다.
  • 다중 상속이 불가능하다. 

 

인터페이스(Interface)

interface 키워드를 사용하여 정의하며, 오직 추상 메서드와 상수(static final)만을 가지고 있는 것을 인터페이스라고 한다. 추상클래스와 마찬가지로 인터페이스 또한 인터페이스 선언되어있는 추상 메서드를 implements 하는 클래스에서(반드시)구현하도록 강제한다.

  • 인터페이스의 모든 맴버 변수는 public static final이어야 하며, 이를 생략가능하다.
  • 인터페이스의 모든 메서드는 public abstract이어야 하며, 이를 생략가능하다.
  • java8 부터는 static, default method를 사용할 수 있다.
  • 인터페이스는 상속 키워드로 implements를 사용한다.
  • 다중상속이 가능하다.
구분 추상 클래스 인터페이스
공통점 객체 생성 객체를 생성(인스턴스)할 수 없다.
추상 메서드 추상 메서드를 포함한다.
기능적 목적 상속받는 클래스에서는 추상 메서드를 반드시 재정의하여 구현해야 한다.
차이점 개념적 목적 상속받아서 기능을 확장시키는 목적 구현 객체의 동일한 실행 기능 보장하기 위한 목적
클래스 클래스. 클래스가 아니다
일반 메서드 일반 메서드 정의가 가능 일반 메서드 정의 불가등(java8 이후 staic, default 메서드 정의가능)
맴버 변수 클래스와 동일하게 변수 선언 및 사용
가능
상수만 사용 가능
*상수(변하지않고 고정된  값)
상속 키워드 extends implements
다중 상속 불가능 가능

 

인터페이스와 코드응집도

  1. 높은 응집도를 유지: 인터페이스는 클래스가 특정 기능에 집중하도록 도와줍니다. 클래스는 인터페이스에서 정의한 메서드들만 구현하면 되므로, 각 클래스는 특정 역할에 집중할 수 있습니다. 이는 클래스 내부의 메서드들이 긴밀하게 관련되어있음을 보장하여 높은 응집도를 유지하게 합니다.
  2. 단일 책임의 원칙: 인터페이스는 단일 책임원칙(Single Responsibility Principle)을 준수하도록 유도합니다. 하나의 인터페이스는 한 가지 역할만 정의하도록 설계되어야 하며, 이를 구현하는 클래스 역시 한 가지 역할에 집중할 수 있습니다.
  3. 유지보수성의 향상: 인터페이스를 사용하여 클래스 간 결합도를 낮추면, 코드 변경 시 영향을 받는 범위가 줄어듭니다. 이는 각 모듈이 독립적으로 동작하게 하여 높은 응집도를 유지하는 데 기여합니다.
  4. 테스트의 용이성: 인터페이스를 통하여 의존성을 주입하면, 테스티 시 Mock 객체 등을 활용하여 각 모듈을 독립적으로 테스트할 수 있습니다. 이는 코드의 응집도를 높이고, 각 모듈의 역할을 명확하게 구분하는 데 도움을 줍니다.

 

인터페이스 예제

// AnimalActions.java
public interface AnimalActions {
    void eat();
    void sleep();
    void makeSound();
}

 

추상클래스 예제

// Animal.java
public abstract class Animal {
    protected String name;
    protected int age;

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void describe() {
        System.out.println("Name: " + name);
        System.out.println("Age: " + age);
    }

    // 추상 메서드: 서브클래스에서 구현해야 함
    public abstract void move();
}

 

추상클래스와 인터페이스를 구현하는 예제

// Dog.java
public class Dog extends Animal implements AnimalActions {
    public Dog(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println(name + " is eating dog food.");
    }

    @Override
    public void sleep() {
        System.out.println(name + " is sleeping in a dog bed.");
    }

    @Override
    public void makeSound() {
        System.out.println(name + " says: Woof!");
    }

    @Override
    public void move() {
        System.out.println(name + " is running.");
    }
}

// Cat.java
public class Cat extends Animal implements AnimalActions {
    public Cat(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println(name + " is eating cat food.");
    }

    @Override
    public void sleep() {
        System.out.println(name + " is sleeping in a cozy spot.");
    }

    @Override
    public void makeSound() {
        System.out.println(name + " says: Meow!");
    }

    @Override
    public void move() {
        System.out.println(name + " is jumping.");
    }
}

 

메인클래스 예제

// Main.java
public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog("Buddy", 3);
        Cat cat = new Cat("Whiskers", 2);

        System.out.println("Dog:");
        dog.describe();
        dog.eat();
        dog.sleep();
        dog.makeSound();
        dog.move();

        System.out.println("\nCat:");
        cat.describe();
        cat.eat();
        cat.sleep();
        cat.makeSound();
        cat.move();
    }
}

 

 

[결과]

추상클래스, 인터페이스 둘다 추상 메서드라는 공통점을 가지고 있으며 독립적으로 객체를 생성할 수 없다는 공통점을 지니고있고 여러곳에 사용될 공통된 기능에 대한 강제구현을 하기위한 기능이 있다. 

인터페이스는 높은 응집도를 유지, 단일책임의 원칙, 유지보수성의 향상, 테스트의 용이성을 가지고 있다.

 

[느낀점]

추상 클래스와 인터페이스 비슷한 모습을 가진 부분에 대하여 공부하였다 시간 날때마다 한번씩 더 봐야할 것 같다.

 

 

 

 

 

 

https://hahahoho5915.tistory.com/70#%EB%-B%A-%EC%A-%--%--%EC%--%--%EC%--%-D%-F

 

 

 

이미지 출처: https://medium.com/swlh/the-easiest-concept-between-library-and-framework-f7c6134dcc6c

 

프레임워크(framework)

원하는 기능 구현에 집중하여 개발할 수 있도록 일정한 형태와 기능을 갖추고 있는 골격, 뼈대를  의미한다.

프레임워크는 애플리케이션 개발 시 필수적인 코드, 알고리증, DB연동과 같은 기능을 위해 어느 정도 구조(뼈대)를 제공하고, 이러한 구조위에서 사용자가 코드를 작성하여 애플리케이션을 개발

앱/서버 등의 구동, 메모리관리, 이벤트 루프 등 공통된 부분은 프레임워크가 관리하고, 사용자는 프레임워크가 정해준 방식대로 클래스, 메소드를 구현, 소프웨어의 특정 문제를 해결하기 위해서 상호협력하는 클래스와 인터페이스의 집합

 

프레임워크의 기능

  1. 코드 재사용성: 프레임워크는 공통 기능을 제공하여 코드재사용에 용이하다.
  2. 일정한 구조 제공: 프레임워크는 어플리케이션 구조를 정의하여 개발자가 그 구조를 따르도록 한다.
  3. 모듈화: 프레임워크는 기능을 모듈화하여 독립적인 컴포넌트로 나룰 수 있게 한다.
  4. 생상선 향상: 반복적인 작업을 자동화하고 개발 생산성을 높인다.
  5. 유지보수성: 일관된 코드 구조를 유지하여 유지보수성을 향상시킨다.

 

라이브러리(Library)

라이브러리는 단순 활용가능한 도구들의 집합이다 소프트웨어를 개발할 때 컴퓨터 프로그램이 사용하는 비 휘발성 자원의 모음 미리 작성된 코드, 변수, 함수, 클래스가 포함

 

라이브러리의 기능

  1. 코드 재 사용성: 라이브러리는 특정 작업을 처리하는 코드의 재사용을 촉진
  2. 추상화: 복잡한 작업을 간단한 함수 호출로 추상화한다.
  3. 모듈화: 라이브러리는 기능별로 모듈화 되어 필요에 따라 가져다 쓸 수 있다.
  4. 유연성: 개발자가 필요에 따라 라이브러리를 선택하여 사용할 수 있다.

 

프레임워크와 라이브러리의 차이점

 

제어의 역전

라이브러리와 프레임워크의 가장 큰 차이는 제어흐름에 대한 주도성이 누구에게/어디에 있는가에 있다. 즉, 애플리케이션 Flow(흐름)을 누가 가지고 있느냐에 달려있다.

프레임워크는 전체적인 흐름을 프레임워크가 가지고 있으며 사용자는 그 안에 필요한 코드를 짜 넣으면 되고, 반면에 라이브러리는 사용자가 전체적인 흐름을 직접 만들고 필요에 따라 라이브러리를 가져다 쓰는 것 

구조 제공 유뮤

프레임워크는 전체 애플리케이션의 구조를 정의하여 일정한 패턴을 따르게 한다.

라이브러리는 특정 기능만을 제공할 뿐 애플리케이션의 전체 구조에는 관여하지 않는다. 사용하는 개발자 스스로 우너 하는 방식으로 구조를 설계할 수 있다.

 

 

 

[결과]

프레임워크가 흐름을 제어하고 사용자가 만든 코드를 사용하고 

라이브러리는 사용자가 흐름을 제어하고 라이브러리를 가져다 사용

 

[느낀 점]

프레임워크와 라이브러리의 차이점 같이 같은 것 같으면서 다른 것들이 많은 것 같다

 

 

참조사이트

https://idkim97.github.io/2022-08-16-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC%20vs%20%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC/#google_vignette

 

[개발상식] 프레임워크(Framework)와 라이브러리(Library)의 차이

프레임워크 라이브러리 차이. 라이브러리 프레임워크 차이.

idkim97.github.io

 

JVM이란

JAVA Virtual Macchine, 자바 가상 머신의 약자를 따서 줄여 부르는 용어이다.

  • JVM의 역할은 자바 어플리케이션을 클래스 로더를 통해 읽어들여 자바API와 함께 실행한다.
  • JVM은 JAVA와 OS 사이에 중개자 역할을 수행하여 JAVA가 OS에 구애받지 않고 재사용가능하게해준다.
  • 메모리관리, Garbage Colletion을 수행

자바프로그램 실행과정

  1. 프로그램이 실행되면 JVM은 OS로 부터 이 프러그램이 필요한 메모리를 할당받는다.
        JVM은 이 메모리를 용도에 따라 여러 영역으로 나누어 관리
  2. 자바 컴파일러(JavaC)가 자바소스(.java)를 읽어들여 자바 바이트코드( .class)로 변환시킨다.
  3. Class Loader를 통하여 class파일을 JVM으로 로딩
  4. 로딩된 class파일들은 Execution engine을 통하여 해석된다.
  5. 해석된 바이트코드는 Runtime Data Areas에 배치되어 실질적인 수행이 이루어진다.
    이러한 실행과정 속에서 JVM은 필요에 따라 Thread Synchronization과 GC같은 작업을 수행한다.

 

 

JVM 구성

1. Class Loader

JVM내로 클래스를 로드하고 링크를 통하여 배치하는 작업을 수행하는 모듈이다. Runtime시 동적으로 클레스를 로드한다.

jar파일 내 저장된 클레스들을 JVM위에 탑재하고 사용하지 않는 클래스들은 메모리에서 삭제한다.(컴파일러 역할)

자바는 동적코드, 컴파일 타임이 아니라 런타임에 참조한다. 즉, 클래스를 처음으로 참조할 때, 해당 클래스를 로드하고 링크한다는 것이다. 

 

2. Execution Engine(실행엔진)

클래스를 실행시키는 역할이다. 클래스 로더가 JVM내 런타임데이터 영역에 바이트 코드를 배치시키고, 이것은 실행엔진에 의해 실행된다. 자바 바이트코드는 기계가 바로 수행할 수 있는 언어보다는 비교적 인간이 보기 편한 형태로 기술된 것이다. 그래서 실행엔진은 이와같은 바이트코드를 실제로 JVM내부에서 기계가 실행할 수 있는 형태로 변경한다. 이때 두가지 방식을 사용하게 된다.

 

3. Garbage Collector(GC)

가비지 컬렉션(Garbage Collection, 이하 GC)은 자바의 메모리 관리 방법 중의 하나로 JVM(자바 가상 머신)의 Heap 영역에서 동적으로 할당했던 메모리 중 필요 없게 된 메모리 객체(garbage)를 모아 주기적으로 제거하는 프로세스를 말한다.

 

4. Runtime Data Area

4-1. Method Area(=Class area = Static area)

클래스 정보를 처음 메모리 공간에 올릴 때 초기화되는 대상을 저장하기 위한 메묄 공간. 올라가게 되는 메서드의 바이트 코드는 프로그램의 흐름을 구성하는 바이트코드이다. 자바 프로그램은 main 메서드의 호출에서부터 계속된 메서드의 호출로 흐름을 이어가기 때문이다. 대부분 인스턴스의 생성도 메서드내에서 명령하고 호출한다. 사실상 컴파일된 바이트코드의 대부분이 메서드 바이트코드이기 때문에 거의 모든 바이트코드가 올라간다고 봐고 무방하다.

 

4-2. Heap

객체를 저장하는 가상 메모리 공간이다 new 연산자로 생성된 객체와 배열을 저장한다. 물론 class area영역에 올라온 클레스들만 객체로 생성할 수 있다.

 

4-3. Stack Area

프로그램 실행과정에서 임시로 할당되었다가 메서드를 빠져나가면 바로 소멸되는 특성의 데이터를 저장하기 위한 영역이다. 각종 형태의 변수나 임시 데이터, 스레드나 메서드의 정보를 저장한다. 메서드 호출 시 마다 각각의 스택프레임(그 메서드만을 위한 공간)이 생성된다. 메서드 수행이 끝나면 프레임 별로 삭제를 한다. 메서드 안에서 사용되는 값들(local variable)을 저장한다. 또 호출된 메서드의 매개변수, 지역변수, 리턴 값 및 연산 시 일어나는 값들을 임시로 저장함.

 

4-4. PC register

Thread가 시작될 때 생성되며, 생성될 때마다 생성되므로 Thread마다 하나씩 존재한다. Thread가 어떤부분을 어떤 명령으로 실행해야할지에 대한 기록을 하는 부분으로 현재 수행중인 JVM 명령의 주소를 갖는다.

 

4-5.

자바 프로그램이 컴파일되어 생성되는 바이트 코드가 아닌 실제 실행할 수 있는 기계어로 작성된 프로그램을 실행시키는 영역이다. Java가 아닌 다른 언어로 작성된 코드를 위한 공간이다. Java Native Interface를 통해 바이트 코드로 전환하여 저장하게 된다. 일반 프로그램 처럼 커널이 스택을 잡아 독자적으로 프로그램을 실행시키는 영역이다. 이 부분을 통하여 C code를 실행시켜 Kernel에 접근할 수 있다.

 

 

[결과]

JVM은 java 소스파일을 java 컴파일러가 Class파일(바이트코드)로 변경 후 클래스로더를 이용해 Method  에어리어에 배치 후 링크작업을 하여 Heap영역 Stack 영역에 정보를 링크하여 자료를 쓰이게 해주고 Execution Engine(실행엔진)이 JIT컴파일러나 인터프리터를 사용하여 실행되며 Garbage Collector(GC)가 할당했던 메모리 중 필요없게된 객체를 모아 주기적으로 제거한다.

 

 

[느낀점]

JVM에 대하여 공부하였다 자바의 컴파일러는 자바 소스코드를 바이트코드(.class) 파일로 변경 후 자바의 JVM이 위 내용처럼 여러 과정을 거쳐 프로그래밍하는 것을 알았다. 좀 더 공부하여 jvm의 성능과 메모리 최적화, gc의 종류선택 과 최적화 방법 등 공부를 해야겠다.

 

 

 

 

참조

https://asfirstalways.tistory.com/158

 

#자바가상머신, JVM(Java Virtual Machine)이란 무엇인가?

#JVM이란?JVM이란 JAVA Virtual Machine, 자바 가상 머신의 약자를 따서 줄여 부르는 용어이다 (가상머신이란 프로그램의 실행하기 위해 물리적 머신과 유사한 머신을 소프트웨어로 구현한 것이다.) JVM

asfirstalways.tistory.com

 

https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EA%B0%80%EB%B9%84%EC%A7%80-%EC%BB%AC%EB%A0%89%EC%85%98GC-%EB%8F%99%EC%9E%91-%EC%9B%90%EB%A6%AC-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%F0%9F%92%AF-%EC%B4%9D%EC%A0%95%EB%A6%AC

 

☕ 가비지 컬렉션 동작 원리 & GC 종류 💯 총정리

Garbage Collection(GC) 이란? 가비지 컬렉션(Garbage Collection, 이하 GC)은 자바의 메모리 관리 방법 중의 하나로 JVM(자바 가상 머신)의 Heap 영역에서 동적으로 할당했던 메모리 중 필요 없게 된 메모리 객

inpa.tistory.com

https://jangjjolkit.tistory.com/32

 

[Java] Java Virtual Machine(JVM) 이란?

JVM이란? JVM이란 Java Virtual Machine, 자바 가상 머신의 약자를 따서 줄여 부르는 용어이다. 가상머신이란 프로그램이 실행하기 위해 물리적 머신과 유사한 머신을 소프트웨어로 구현한 것 JVM은 스택

jangjjolkit.tistory.com

 

Garbage Collection(GC) 탄생배경

프로그래머가 동적으로 할당한 메모리 영역 중 사용되지 않는 영역을 자동으로 식벼하고 해제하는 기능으로 이 개념은 1959년 존 매카시(Jon McCarthy)가 LISP 언어의 메모리 관리를 위해 처음 도입했다고 알려져있다.

 

과거 프로그래밍 언어들은 동적 메모리 할당기능이 전혀 없거나, C 계열 언어와 같이 프로그래머가 직접 메모리를 할당 한 뒤 수동으로 해제하는 방식을 사용하였으나 프로그래머의 메모리 관리가 완벽하지 않을 수 있기 때문에 메모리 누수, 이미 해체된 메모리의 재사용, 해제된 메모리를 다시 해제하는 등 실수로 인해 많은 버그와 취약점이 밟생할 수 있었고 재현 불가능한 오류를 발생시키기도 하여, 프로그래머들에게 엄청난 디버깅 난이도를 주었습니다.


 

Garbage Collection(GC)

가비지 컬렉션(Garbage Collection, 이하 GC)은 자바의 메모리 관리방법 중의 하나로 JVM(자바 가상머신)의 Heap영역에서 동적으로 할당했던 메모리 중 필요 없게 된 객체(garbage)를 모아 주기적으로 제거하는 프로세스

 

장점

  • 가비지 컬렉터가 메모리 관리를 대행해주기때문에 한정된 메모리를 효율적으로 사용, 개발자입장에서의 메모리 관리, 메모리 누수의 문제에 대하여 완벽히 관리하지 않고 개발에만 집중가능

 

단점

  • 개발자가 메모리가 언제 해제되는지 정확하게 알 수 없다.
  • 가비지 컬렉션이 동작하는 동안에는 다른 동작을 멈추기 때문에 오버헤드(어떤 처리를 하기 위해 들어가는 간접적인처리 시간 · 메모리 등)가 발생한다.
    ** 위 단점을 Stop-The-World라고 한다

 

Stop-The-World

GC를 수행하기 위해 JVM이 프로그램 실행을 멈추는 현상을 의미

GC가 작동하는 동안 GC관련 Thread를 제외한 모든 Thread는 멈추게되어 서비스이용에 차질이 생길 수 있다.

예로 익스플로어는 이 가비지 컬랙션을 너무 자주 실행하여 성능에 문제를 일으키는 것으로 악명 높았다.
실시간성이 매우 강조되는 프로그램일 경우 가비지컬렉터에게 메모리를 맞기는 것은 맞지 않을 수 있다. 

 

가비지 컬렉션(GC)의 대상이 되는 객체

 

가비지 컬렉션은 특정객체가 garbage인지 판단하기 위하여 도달성, 도달능력(Reachability)이라는 개념을 적용.

객체에 레퍼런스가 있다면 Reachable로 구분, 객체에 유효한 레퍼런스가 없다면 Unreachable로 구분하여 제거

 

 

GC의 대상이 되는 heap메모리의 구조

JVM의 힙(heap)영역은 동적으로 레퍼런스 데이터가 저장되는 공간으로서, 가비지 컬렉션에 대상이 되는 공간이다.

heap영역은 처음 설계될 때 다음의 2가지 전제로 설계되었다

  • 대부분의 객체는 금방 접근 불가능한 상태(Unreachable)가 된다.
  • 오래된 객체에서 새로운 객체로의 참조는 아주 적게 존재한다.

 

즉, 객체는 대부분 일회성이며 메모리에 오랫동안 남아있는 경우는 드물다.

이러한 특성을 이용해 JVM 개발자들은 보다 효율적인 메모리 관리를 위해, 객체의 생존기간에 따라 물리적인 heap 영역을 나누게 되었고 Young와 Old 총 2가지 영역으로 설계하였다

 

가비지 컬렉션(GC)과정

GC는 크게 Young영역과 Old영역으로 나뉘어진다(Perm영역은 Java8 버전 이후에는 Native Method Stack에 편입)

Young 영역

  • 새롭게 생성한 객체가 할당(Allocation)되는 영역
  • 대부분의 객체가 금방 접근 불가능 상태(Unreachable)가 되기 때문에 많은 객체가  Young영역에 생성되었다. 사라진다.
  • Young 영역에 대한 가비지 컬렉션 Minor GC가 발생한다고 말한다.

 

Young 영역의 구성

  •  Eden 영역
    new를 통해 새로 생성된 객체가 위치.
    정기적인 쓰레기 수집 후 살아남은 객체들은 Survivor 영역으로 보냄
  • 두개의 Survivor 영역
    최소 1번의 GC 이상 살아남은 객체가 존재하는 영역
    Survivor 영역에는 특별한 규칙이 있는데, Survivor 0 또는 Survivor 1 둘중 하나에는 꼭 비어있어야 한다.

  1. 새로 생성된 객체 대부분은 Eden 영역에 위치
  2. Eden 영역에서 GC가 한번 발생한 후 살아남은 객체는 Survivor영역 중 하나로 이동
  3. GC가 발생하면 이미 살아남은 객체가 존재하는 Survivor영역에 객체가 계속 쌓임
  4. 하나의 Survivor영역이 가득 차면 살아남은 객체를 다른 Survivor 영역으로 이동하여 하나의 Survivor 영역을 비워줌
  5. 이런 GC과정을 통해 살아남은 객체는 Old 영역으로 이동

 

Old영역

  • Young영역에서 Reachable 상태를 유지하여 살아남은 객체가 복사되는 영역
  • Young 영역보다 크게 할당되며, 영역의 크기가 큰 만큼 가비지는 적게 발생한다.
  • Old 영역에 대한 가비지 켤렉션(garbage Collection)을 Major GC 또는 Full GC라고 부른다. 

 

 

가비지컬렉션(GC)의 종류

1. Serial GC

  • 서버의 CPU 코어가 1개일 때 사용하기 위해 개발된 가장 단순한 GC
  • GC를 처리하는 Threa가 1개 (싱글 쓰레드)여서 가장 Stop-The-World 시간이 길다
  • Minor GC는 Mark and Sweep를 사용하고, Major GC는 Mark and Sweep-Compact를 사용한다.
  • 보통 실무에서 사용하는 경우는 거의 없다(디바이스 성능이 안좋아서 CPU코어가 1개인 경우에만 사용)

 

Mark and Sweep

  • Mark:사용되는 메모리와 사용되지 않는 메모리를 식별하는 작업
  • Sweep: Mark 단계에서 사용되지않음으로 식별된 메모리를 해체하는작업

 

2. Parallel GC

  • Java8의 디폴트 GC
  • Serial GC와 기본적인 알고리즘은 같지만,Young 영역의 MinorGC를 멀티쓰레드로 수행(Old 영역은 싱글쓰레드 사용)
  • Serial GC에 비해 Stop-The-World  시간 감소

 

3. Parallel Old GC(Parallel Compacting Collector)

  • parallel GC를 개선한 버전
  • Young 영역과 Old 영역에서도 멀티 Thread로 GC 수행
  • 새로운 가비지 컬렉션 청소방식인 Mark-Summary-Compact 방식을 이용

 

4. CMS GC(Concurrent Mark Sweep)

  • 어플리케이션의 쓰레드와 GC쓰레드가 동시에 실행되어 Stop-The-World 시간을 최대한 줄이기 위해 고안된 GC단, GC과정이 매우 복잡해짐
  • GC  대상을 파악하는 과정이 복잡한 여러단계로 수행되기 때문에 다른 GC대비 CPU사용량이 높다
  • 메모리 파편화 문제
  • CMS GC는 Java9 버전부터 deprecated되었고 결국  Java14에서는 사용이 중지

 

5. G1GC(Garbage First)

  • CMS GC를 대체하기 위하여 jdk7 버전에서 최초로 release된 GC
  • Java9+ 버전의 디폴트 GC로 지정
  • 4GB 이상의 힙메모리, Stop-The-World 시간이 0.5초 정도 필요한 상황에 사용(Heap가 너무 작을경우 미사용 권장)
  • 기존의 GC알고리즘에서는 heap영역을 물리적으로 고정된 Young/Old영역으로 나누어 사용하였지만,G1GC는 완전히 이러한 개념을 뒤엎는 Region이라는 영역으로 체스같이 분할하여 상황에 따라 Eden, Survivor, Old 등 역할을 고정이 아닌 동적으로 부여
  • Garbage로 가득찬 영역을 빠르게 회수하여 빈 공간을 확보하므로, 결국 GC 빈도가 줄어드는 효과를 얻게되는 원리
  • pause 시간을 예측하기 어려움 특정 상황에서는 pause시간을 예측하기 어려울 수 있다 특히, 높은 메모리 사용량이나 급격한 객체 생성/삭제 패턴이 있는 어플리케이션에서는 예상하지 못한 긴 pause시간이 발생할 수 있음

 

6. Shenandoah GC

  • Java12에 release
  • 레드햇에서 개발한 GC
  • 기존 CMS가 가진 단편화, G1이 가진 Pause의 이슈를 해결
  • 강력한  Concurrency와 가벼운 GC로직으로 heap 사이즈에 영향을 받지 않고 일정한 pause 시간 소요가 특징

 

7. ZGC (Z Garbage Collector)

  • Java 15에 release
  • 대량의 메모리(8MB ~ 16TB)를 low-latency로 잘 처리하기 위해 디자인된 GC
  • G1의 Region처럼 ZGC는 ZPage라는 영역을 사용하며, G1의 Region은 크기가 고정인데 비해, ZPage느 2mb 배수로 동적 운영됨. (큰 객체가 들어오면 2^로 영역을 구성해서 처리)
  • ZGC가 내세우는 최대 장점 중 하나는 힙 크기가 증가하더라도 Stop-The-World 시간이 절대 10ms를 넘지 않음

 

[결과]

Garbage Collector은 쓰레기 값을 정리하며  Eden 영역 -> servivor 영역 -> old영역으로 이동하며 young 영역과 old 영역의 가장 큰 차이점은 Stop The Wolrd가 old영역에는 없다는 것이다.

 

[느낀점]

Garbage Collector가 메모리 관리를 하여 개발자가 메모리 관리외의 다른 부분에 신경을 쓸 수 있게 되어 좋은 점도 있지만 GC가 자주발생하게되면 Stop The World가 자주 발생하게 되는데 이에따른  성능저하에 대한 관리에대하여 공부를 해야겠다

 

 

참고사이트

https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EA%B0%80%EB%B9%84%EC%A7%80-%EC%BB%AC%EB%A0%89%EC%85%98GC-%EB%8F%99%EC%9E%91-%EC%9B%90%EB%A6%AC-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%F0%9F%92%AF-%EC%B4%9D%EC%A0%95%EB%A6%AC

 

☕ 가비지 컬렉션 동작 원리 & GC 종류 💯 총정리

Garbage Collection(GC) 이란? 가비지 컬렉션(Garbage Collection, 이하 GC)은 자바의 메모리 관리 방법 중의 하나로 JVM(자바 가상 머신)의 Heap 영역에서 동적으로 할당했던 메모리 중 필요 없게 된 메모리 객

inpa.tistory.com

 

https://velog.io/@ririti/JAVA%EC%9D%98-Garbage-CollectionGC-%EA%B0%80%EB%B9%84%EC%A7%80-%EC%BB%AC%EB%A0%89%EC%85%98-%EB%8F%99%EC%9E%91%EC%9B%90%EB%A6%AC

 

https://s-y-130.tistory.com/111

 

[JAVA] 가비지 컬렉션(Garbage Collection) 동작 원리 & GC 종류

가비지 컬렉션(Garbage Collection)이란? 가비지 컬렉션(Garbage Collection, 이하 GC)은 자바의 메모리 관리 방법 중의 하나로 JVM(자바 가상 머신)의 Heap 영역에서 동적으로 할당했던 메모리 영역 중 필요 없

s-y-130.tistory.com

https://mirinae312.github.io/develop/2018/06/04/jvm_gc.html

 

Java 의 GC는 어떻게 동작하나? - J's log

Java 프로세스가 동작하는 과정에서 GC는 불필요한 또는 더이상은 사용하지 않는 객체들을 메모리에서 제거함으로써, Java 프로세스가 한정된 메모리를 효율적으로 사용할 수 있게 해준다. 또한 JV

mirinae312.github.io

https://theworldaswillandidea.tistory.com/m/entry/Garbage-Collector-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8%EC%9D%98-%EC%8A%A4%EC%BA%90%EB%B9%88%EC%A0%80#google_vignette

 

Garbage Collector, 프로그램의 스캐빈저

오늘은 프로그래머의 뒤처리를 담당해 주는 가비지 컬렉터(Garbage Collector, GC)에 대해서 알아보도록 합시다. 메모리 관리 방법 중 하나인 가비지 컬렉션(Garbage Collection)은 프로그래머가 동적으로

theworldaswillandidea.tistory.com

 

JIT(Just In Time) 컴파일러

 프로그램을 실제 실행하는 시점에 기계어로 번역하는 컴파일 기법이다.(JIT 컴파일 = 인터프리터 방식 + 컴파일 방식)

  • 컴파일 방식: 소스코드를 한번에 컴퓨터가 읽을 수 있는 native machine(기계어)로 변환
  • 인터프리터 방식: 소스코드를 빌드 시에는 아무것도 하지않다 런타임시에 한줄씩 변환

 

컴파일 방식과 인터프리터 방식의 장단점

  인터프리터 컴파일
특징 코드를 한줄 씩 읽어나가며 실행 소스코드 전체를 한번에 번역
번역속도 빠르다 느리다
실행속도 느리다 빠르다
종속성 플랫폼(하드웨어)에 종속적이지 않음 플랫폼(하드웨어)에 종속적

 

바이트코드로 번역된 코드를 캐싱 후 반복적으로 쓰이는 함수와 클래스 등의 기계어코드의 캐싱해둔 값을 사용하여 매번 기계어 코드가 생성되는 것을 방지해 인터프린트 시간을 단축시킨다.

 

 

인터프리터 조건

JVM이 호출되는 메서드 각각에 대해 호출마다 호출 횟수를 누적해서 그 횟수가 특정 수치(컴파일 임계치)를 초과 할 때 컴파일을 하는데 얼마나 자주 호출되는지 검사 후 

 

컴파일 임계치

  •  method entry counter ( JVM 내에 있는 메서드가 호출된 횟수)
  •  back-edge loop counteer ( 메서드가 루프를 빠저나오기까지 루프 한 횟수 )

위의 두 카운터의 합계를 확인하고 메서드가 컴파일 될 자격이 있는지 결정 메서드가 컴파일될 조건이 맞으면 해당 메서드는 컴파일되기 위하여 큐에서 대기한다. 

 

 

 

JIT 컴파일을 확인해보자

 

1)  먼저 아래 코드를 작성

public class Test{
	public static void main(String [] args){
	for(int i = 0; i < 1000; i++){
		f1();
		}

	}
	private static void f1(){
		int a = 10;
		int b = 1241412;
		for(int i = 0; i <1000; i++){
			int c = a*b;
		}
	}
}

 

2) 커맨드창에서 컴파일

javac C:\godofjava\c\Test.java

3) 커맨드창에서 일단 이렇게 입력해보자

java -Xint -XX:+PrintCompilation C:\godofjava\c\Test.java

 

4) 아래와 같이 화면이 나온다.

 

 

[결과]

위 컴파일된 결과를 본다면 첫번째 열은 가상머신이 시작된 이후 경과된 시간(밀리초) 두번째열은 컴파일된ID이다 이 값이 순서대로 정렬되어있지 않은 경우는 다른부분보다 컴파일하는 시간이 오래 경과되었다는 것  멀티스레딩이나 컴파일되는 코드의 복잡성 또는 길이로 인하여 발생할 수 있다

 

[느낀점]

JIT 컴파일러의 작동방식의 세부 내용, JIT 컴파일러의 최적화 등 모르는 것이 많아 좀더 글을 수정 업데이트 해야겠습니다

 

 

 

 

참조사이트

https://gist.github.com/rednaxelafx/1165804#file_notes.md

 

PrintCompilation samples running Groovy shell 1.7.7 on different versions of HotSpot VM

PrintCompilation samples running Groovy shell 1.7.7 on different versions of HotSpot VM - JDK5u22_client.log

gist.github.com

https://velog.io/@lucius__k/JIT-%EC%BB%B4%ED%8C%8C%EC%9D%BC%EB%9F%AC%EC%99%80-%EC%BD%94%EB%93%9C-%EC%BA%90%EC%8B%9C

 

JIT 컴파일러와 코드 캐시

Compilation자바 코드를 컴파일러(javac)를 사용하여 컴파일하면 바이트 코드(class 파일)로 컴파일된다.그리고 JVM이 해당 자바 바이트코드를 인터프리팅하며 애플리케이션이 실행된다.그러므로 자바

velog.io

 

https://catch-me-java.tistory.com/11

 

[Java-3] JVM과 JIT 컴파일러란?

전 글에서는 JAVA의 바이트 코드에 대해서 알았다. 이번에는 그 바이트코드를 가지고 어떻게 실행하는지 알아보기 위해, 기본적인 JVM의 JIT 에 대해서 알아보도록 하자. 먼저 실행을 하기 위해서

catch-me-java.tistory.com

 

https://beststar-1.tistory.com/3

 

JIT(Just In Time) 컴파일러

목차 배경 지난번 JVM 메모리 영역의 역할과 구조에 대해 알아봤다. beststar-1.tistory.com/14 JVM(Java Virtual Machine, 자바 가상 머신) - 3. 메모리 영역 목차 배경 지난번 JVM의 클래스로더 시스템의 역할과

beststar-1.tistory.com

https://junshock5.tistory.com/111

 

Jit 컴파일러란? 최적화 튜닝에 대해서

*JIT(Just In Time Compiler 개념 및 튜닝) 한 번만 실행될 코드라면 인터프리터가 빠르다, 하지만 많이 실행될 코드라면 컴파일을 하는것이 좋다. JIT(그때그떄, 그래서 언제?) 핫스팟 JVM은 코드를 바로

junshock5.tistory.com

 

+ Recent posts