Java
-
Thread와 RunnableJava 2023. 4. 11. 20:28
쓰레드와 자바의 멀티 쓰레드 쓰레드란 프로그램 실행의 가장 작은 단위이다. 자바 애플리케이션을 만들어 실행하면 1개의 메인 쓰레드에 의해 프로그램이 실행된다. 하지만 1개의 쓰레드 만으로는 동시에 여러가지 작업을 할 수 없다. 동시에 여러 작업을 처리하고 싶다면, 별도의 쓰레드를 만들어 실행시켜주어야 한다. 자바는 멀티 쓰레드 기반으로 동시성 프로그래밍을 지원하기 위한 방법들을 계속해서 발전시켜 왔다. 쓰레드를 생성하는 방법은 크게 두 가지로 나눌 수 있다. 1. Thread클래스를 상속받아 run() 메소드를 오버라이딩 2. Runnable 인터페이스 구현 객체를 생성한 후 Thread 생성자로 Runnable 객체 전달 2가지 방법 모두 run() 메서드를 재정의하고 있고, 결과적으로 Thread 객..
-
Java 메모리 누수(Memory Leak), GC 튜닝Java 2023. 3. 30. 00:35
메모리 누수 자바에서 메모리 누수는 더 이상 사용되지 않는 객체들이 GC(가비지 컬렉션)에 의해 소멸되지 않고 누적되는 현상이다. 가비지 컬렉션의 소멸 대상이 되려면 다른 Reference 변수에서 참조하고 있지 않아야 한다. 예시 1. Static 변수가 객체를 참조하고 있다면, 해당 객체는 GC에 의해 소멸되지 않는다. - Static 변수는 프로그램 종료 시점에 메모리가 반환되고, 사용하지 않아도 메모리를 점유하고 있다. 이런 static 변수를 재사용한다면 이점이 있지만, 사용하지 않으면 메모리를 점유하고 있게 된다. 2. Stack에서 Heap에 있는 객체를 참조하고 있는 동안에는 해당 객체는 GC에 의해 소멸되지 않는다. 메모리 누수가 발생하는 패턴 1. 무의미한 Wrapper 객체를 생성하는..
-
JVM 메모리 구조Java 2023. 3. 9. 20:05
JVM은 Java Virtual Machine의 약자로, 자바 가상 머신이라고 부르며 자바 프로그램 실행환경을 만들어 주는 소프트웨어다. 자바 코드를 컴파일하여 .class 바이트 코드로 만들면 이 코드가 자바 가상 머신 환경에서 실행된다. 자바와 운영체제 사이에서 중개자 역할을 수행하며, 자바가 운영체제에 구애 받지 않고 프로그램을 실행할 수 있도록 도와준다. 또한, 가비지 컬렉터를 사용한 메모리 관리도 자동으로 수행하며, 스택 기반으로 동작한다. JVM을 사용함으로써 얻는 가장 큰 이점은 JVM을 사용하면 하나의 바이트 코드(.class)로 모든 플랫폼에서 동작하도록 할 수 있다는 점이다. C언어로 작성된 Test.c를 윈도우 컴파일러를 사용하여 컴파일하면 Test.exe가 만들어진다. 윈도우 컴파일..
-
[Effective Java] wait와 notify보다는 동시성 유틸리티를 애용하라Java 2023. 2. 14. 02:44
wait와 notify보다는 동시성 유틸리티를 애용하라 자바 5에서 도입된 고수준의 동시성 유틸리티가 이전이라면 wait와 notify로 하드코딩해야 했던 전형적인 일들을 대신 처리해주기 때문에 지금은 wait과 notify를 사용해야 할 이유가 많이 줄었다. 갖고 있던 고유 락을 해제하고, 스레드를 잠들게 하는 wait와 잠들어 있던 스레드 중 임의로 하나를 골라 깨우는 notify는 synchronized 블록이나 메소드에서 호출되어야하고, 올바르게 사용하기가 아주 까다로우니 고수준 동시성 유틸리티를 사용하자. java.util.concurrent의 고수준 유틸리티는 세 범주로 나눌 수 있다. 실행자 프레임워크, 동시성 컬렉션, 동기화 장치다. 동시성 컬렉션 동시성 컬렉션은 List, Queue, M..
-
[Effective Java] 스레드보다는 실행자, 태스크, 스트림을 애용하라Java 2023. 2. 14. 02:43
스레드보다는 실행자, 태스크, 스트림을 애용하라 책 초판의 아이템 49에서는 단순한 작업 큐(work queue) 클래스는 클라이언트가 요청한 작업을 백그라운드 스레드에 위임해 비동기적으로 처리해줬다. 작업 큐가 필요 없어지면 클라이언트는 큐에 중단을 요청할 수 있고, 그러면 큐는 남아 있는 작업을 마저 완료한 후 스스로 종료한다. 안전 실패나 응답불가가 될 여자를 없애는 코드를 추가해야 했기 때문에 코드가 길고 복잡했다. java.util.concurrent 패키지 java.tuil.concurrent 패키지가 등장하면서 더이상 위와 같은 코드를 작성하지 않아도 됐다. 이 패키지는 실행자 프레임워크라고 하는 인터페이스 기반의 유연한 태스크 실행 기능을 담고 있다. 그래서 모든 면에서 뛰어난 작업 큐를 ..
-
[Effective Java] 필요 없는 검사 예외 사용은 피하라Java 2023. 2. 6. 12:47
필요 없는 검사 예외 사용은 피하라 검사 예외를 싫어하는 자바 프로그래머가 많지만 제대로 활용하면 API와 프로그램의 질을 높일 수 있다. 결과를 코드로 반환하거나 비검사 예외를 던지는 것과 달리, 검사 예외는 발생한 문제를 프로그래머가 처리하여 안정성을 높이게끔 해준다. 물론, 검사 예외를 과하게 사용하면 오히려 쓰기 불편한 API가 된다. 어떤 메서드가 검사 예외를 던질 수 있다고 선언됐다면, 이를 호출하는 코드에서는 catch 블록을 두어 그 예외를 붙잡아 처리하거나 더 바깥으로 던져 문제를 전파해야 한다. 검사 예외 회피 방법 - 1. 비검사 예외 API를 제대로 사용해도 발생할 수 있는 예외이거나, 프로그래머가 의미 있는 조치를 취할 수 있는 경우라면 이 정도 부담쯤은 받아들일 수 있을 것이다...
-
[Effective Java] 복구할 수 있는 상황에는 검사 예외를, 프로그래밍 오류에는 런타임 예외를 사용하라Java 2023. 2. 6. 12:46
복구할 수 있는 상황에는 검사 예외를, 프로그래밍 오류에는 런타임 예외를 사용하라 자바는 문제 상황을 알리는 타입(throwable)으로 검사 예외, 런타임 예외, 에러, 이렇게 세 가지를 제공한다. 검사 예외 개발자가 명시해야 하는 부분은 검사 예외인 Exception으로 어플리케이션 수행 중 일어날 법한 예외를 검사하고 대비하라는 목적으로 사용된다. 컴파일 단계에서 컴파일러가 체크한다. 이를 처리하지 않으면 컴파일 에러가 발생한다. 과도한 예외 검출은 시스템의 성능을 저하시킬 수 있다. 비검사 예외 Error는 시스템적인 예외를 의미한다. 개발자가 예외를 try-catch 로 잡지 않았을 때 발생한다. 런타임에 컴파일러에게 예외가 걸리지지 않았을 경우 발생한다. 즉, 코드 상의 문제이다. 대표적으로 ..
-
[Effective Java] 예외는 진짜 예외 상황에만 사용하라Java 2023. 2. 6. 12:45
예외 예외를 제대로 활용한다면 프로그램의 가독성, 신뢰성, 유지보수성이 높아지지만, 잘못 사용하면 반대의 효과만 나타난다. 예외는 진짜 예외 상황에만 사용하라 예외를 사용한 반복문은 코드를 헷갈리게 하고 성능을 떨어뜨린다. // 예외를 완전히 잘못 사용한 예 try{ int i = 0; while(true) range[i++].climb(); } catch (ArrayIndexOutOfBoundsException e){ } 위의 코드는 전혀 직관적이지 않다. 이 코드는 배열의 원소를 순회하는데, 아주 끔찍한 방식으로 하고 있다. 무한루프를 돌다가 배열의 끝에 도달해 ArrayIndexOutOfBoundsException이 발생하면 끝을 내는 것이다. 다음과 같이 표준적인 관용구대로 작성했다면 모든 자바 ..