Stack은 왜 상속의 실패 사례일까?
·
💻 Dev/Java & OOP
Java에서 Stack 클래스는 종종 "상속의 실패 사례"나 "디자인이 망가진 클래스"로 언급된다.뭐 때문인지 알아보자! Vector를 잘못 상속받았다.Stack 클래스의 가장 큰 문제는 Vector 클래스를 상속받았다는 점이다.Stack의 선언을 보면 다음과 같다.public class Stack extends Vector {Stack은 LIFO(Last In, First Out) 방식의 스택 자료구조를 구현하기 위해 설계되었지만, Vector는 일반적인 동적 배열을 나타낸다. 근데 뭐가 문제라는걸까? 🤔Stack이 Vector를 상속받았다는 것은 Vector의 모든 메서드를 사용할 수 있다는 것을 말한다. `Vector`는 일반적인 동적 배열 자료구조기 때문에 원래 스택에서는 허용되지 않을 중간에 ..
System.out.println을 실무에서 사용하면 안되는 이유
·
💻 Dev/Java & OOP
자바를 접하게 되면 제일 먼저 하는 것이 System.out.println("Hello, World!")일 것이다.그만큼 기초이자, 아주 많이 사용하는 코드이다.하지만 System.out.println은 실무에서 절대 사용하지 말라고들 한다. 왜일까?성능 이슈로는 크게 2가지가 있다. 블로킹 I/O작업을 한다는 점과 멀티스레드에서 락이 발생한다는 점이다. 1. 블로킹 I/O 작업먼저 System 클래스의 static 변수인 out은 PrintStream 타입의 인스턴스이다.public static final PrintStream out = null;그리고 PrintStream 클래스는 java의 io 패키지 내에 있다.package java.io;public class PrintStream extends..
가비지 컬렉터(GC)의 Roots
·
💻 Dev/Java & OOP
자바에서 가비지 컬렉터(GC)의 GC Roots는 힙 메모리에서 객체를 도달 가능한 상태로 유지하는 시작 지점이다.  GC는 메모리에서 더 이상 사용되지 않는 객체를 식별하고(Mark) 회수하는 작업(Sweep)을 수행하는데, 이때 어떤 객체가 사용 중인지 판단하기 위해 GC Roots에서 시작하여 도달할 수 있는 객체를 활성객체로 간주한다. GC Roots로 간주되는 객체들어떤 게 Roots다! 라고 딱 정해진 건 없지만 일반적으로 다음과 같은 객체들이 GC Roots로 간주된다. 1. 클래스(Class)JVM의 시스템 클래스 로더에 의해 로드된 클래스는 메서드 영역(Method Area)에 저장되며, 클래스의 정적 필드와 메서드는 프로그램 전반에서 전역적으로 접근 가능하다.이러한 정적 필드가 참조하는..
Out-of-Memory(OOM)는 왜 발생하고, 어떻게 예방할까?
·
💻 Dev/Java & OOP
Java 애플리케이션을 개발하다 보면 OutOfMemoryError라는 런타임 에러를 마주칠 때가 있다.JVM이 더 이상 메모리를 할당할 수 없을 때 발생하는 이 에러는 코드나 환경 문제를 나타내는 강력한 신호다.그래~서 OOM 에러가 발생하는 이유와 이를 예방하기 위한 방법을 알아보았다. Out-of-Memory 에러는 언제 발생할까?OOM 에러는 자바의 메모리 구조와 밀접한 관련이 있다.JVM은 Heap, Stack, Metaspace 등으로 나뉘어 메모리를 관리하는데 이 중 특정 영역이 고갈되면 문제가 생긴다.각각의 상황을 예제와 함께 살펴보자. 1. Heap 메모리가 부족한 경우Heap 영역은 객체를 저장하는 공간이다. 프로그램이 너무 많은 객체를 생성하거나 메모리를 효율적으로 관리하지 못하면 고..
instanceof 사용을 지양해야하는 3가지 이유
·
💻 Dev/Java & OOP
상속, 다형성 파트를 배울 때 무조건 학습하게 되는 instanceof에는 3가지 원칙을 위반하는 단점이 존재한다. 그게 뭔지 알아보자 레쓰고 instanceof란?자바에서 객체가 특정 클래스의 인스턴스인지 확인하는 데 사용하는 연산자이다.abstract class Animal {}class Dog extends Animal {}class Cat extends Animal {}위와 같은 상속 관계일 때public class AnimalGame { public void makeSound(Animal animal) { if (animal1 instanceof Dog) { //생략 } if (animal2 instanceof Cat) { //..
JVM Warm-up, feat. 스프링 첫 요청이 오래 걸리는 이유
·
💻 Dev/Java & OOP
원인웹 애플리케이션을 실행한 후 초기 요청이 지연되는 현상을 이해하려면, 자바 프로그램이 실행되는 방식을 깊이 살펴볼 필요가 있다.C, C++과 같은 컴파일 언어는 소스 코드를 기계어로 직접 변환하여 최적화된 성능을 제공하나 빌드 환경에 종속적이라는 단점이 있다.즉, 플랫폼이 바뀌면 재컴파일이 필요하다. 자바는 이러한 플랫폼 종속적인 문제를 해결하고자 JVM을 도입하였다.자바는 자바 코드는 컴파일 시 바이트 코드로 변환되고, 실행 시 JVM이 이를 기계어로 변환하여 실행한다.이러한 구조 덕분에 Java는 플랫폼에 종속되지 않게 되었지만, 이 과정에서 변환 작업이 추가되므로 성능에 영향을 미칠 수 있다. 1. 클래스 로더JVM에서 클래스 로더(Class Loader)는 바이트 코드를 메모리에 로드하는 역할..