본문 바로가기

JAVA

(8)
[Java] Garbage Collection & Garbage Collector Java에서는 개발자가 따로 메모리 관리에 신경써도 되지 않는다는 장점은 많이들 알고 있다. 이것이 가능한 이유는 JVM의 Garbage Collector가 Garbage Collection(GC)이라는 기법으로 알아서 메모리 관리를 해주기 때문이다. 이 글에서는 GC에 대한 개념과 JVM에서 GC를 구현한 다양한 모델들에 대해 정리해보았다. 메모리 관리를 하지 않아도 되는 것이 장점이지만 GC와 JVM의 특성을 잘 알면 어떻게 해야 더 메모리를 잘 관리할 수 있는지, 어떻게 GC 튜닝을 할지 쉽게 이해할 수 있다.  Garbage Collection이란?GC는 메모리 관리 기법 중 하나로, 프로그램이 동적으로 할당했던 메모리 영역 중에서 필요없게 된 영역을 해제하는 기법이다. 필요없게 된 영역이란 더 ..
[Java] JVM이란? 자바는 운영체제에 독립적으로 실행이 가능한 고수준의 객체지향 프로그래밍 언어입니다. 자바의 아버지인 제임스 고슬링에 따르면 다음과 같은 특징을 지닙니다.간단하다 (Simple)객체 지향적이다 (Object Oriented)분산처리를 지원한다 (Distributed)멀티쓰레드를 지원한다 (Multithreaded)동적 로딩을 지원한다 (Dynamic)실행환경에 대해 중립적이다 (Architecture neutral)이식성이 높다 (Portable)고성능 (High Performance)신뢰성이 높다 (Robust)보안성을 갖는다 (Secure)이 특징들 중 많은 부분이 JVM(Java Virtual Machine, 가바 가상 머신)으로 인해 가능합니다. 이 글에서는 JVM의 구조와 역할에 대해서 정리해보고..
자바 레벨에서의 동시성 사람들은 컴퓨터를 사용하면서 여러 가지를 동시에 할 수 있는 것을 당연하게 생각한다. 예를 들면 인터넷 쇼핑을 하면서 백그라운드에서는 유튜브를 통해 음악을 들을 수도 있고, 카카오톡을 주고 받는 것처럼 말이다. 컴퓨터는 이런저런 일들을 처리해주는 와중에도 사용자가 마우스를 움직이면 즉시 커서를 이동해주고 클릭에도 반응한다. 이를 가능하게 해주는 소프트웨어를 concurrent software라고 한다. 자바는 만들어질 당시부터 기본적으로 동시성을 지원하도록 설계가 되었다. 이와 관련된 개념들을 소개하기 전에 ‘프로세스’와 ‘스레드’를 먼저 간단히 이해해보자. 프로세스와 스레드 프로세스 프로그램이 실행되는 데 필요한 모든 것들이 저장되어 있는 자료구조 Text, Program Counter and Regi..
DateTime 자동 저장 시 OS에 따른 Time Precision 문제 프로젝트를 진행하던 중 다른 팀원들의 컴퓨터에서는 RoadmapRepositoryTest의 테스트코드가 잘 돌아가지만 이상하게 내 컴퓨터에서만 테스트의 일부가 실패하는 일이 발생함. 추가적으로 실행시킬 때마다 실패하는 테스트가 다른 기이한 현상까지 발생. 내 컴퓨터만 Windows였고 다른 팀원들의 컴퓨터는 Mac이었기에 일단 운영체제에 따른 오류가 있는 것으로 일단 추측하고 일단 Jenkins를 통해 빌드하기로 결정했다. 하지만 이게 웬걸? Jenkins에서도 내 컴퓨터와 똑같은 부분에서 테스트가 실패해서 빌드가 안 됐다. 결국 문제 상황을 재현 가능한 환경이 내 컴퓨터뿐이었기에 하나하나 실험을 하며 원인을 찾아보았다. 실패하는 테스트의 특징 무한스크롤을 처리하는 로직이다. 무한스크롤 처리 시 data..
[Effective Java] equals를 재정의하려거든 hashCode도 재정의하라 equals를 재정의한 클래스 모두에서 hashCode도 재정의해야 한다. 그렇지 않으면 hashCode 일반 규약을 어기게 되어 해당 클래스의 인스턴스를 HashMap이나 HashSet같은 컬렉션의 원소로 사용될 때 문제를 일으킨다. 👍 hashCode 재정의 규약 equals 비교에 사용되는 정보가 변경되지 않았다면, 애플리케이션이 실행되는 동안 그 객체의 hashCode 메서드는 몇 번을 호출해도 일관되게 항상 같은 값을 반환해야 한다. 단, 애플리케이션을 다시 실행한다면 이 값이 달라져도 상관없다. equals(Object)가 두 객체를 같다고 판단했다면, 두 객체는 hashCode는 똑같은 값을 반환해야 한다. (특히 중요🤩🤩) equals(Object)가 두 객체를 다르다고 판단했더라도, 두 ..
[Effective Java] equals는 일반 규약을 지켜 재정의하라 🧐 equals를 재정의할 필요가 없는 경우 각 인스턴스가 본질적으로 고유하다. 인스턴스의 '논리적 동치성'을 검사할 일이 없다. 상위 클래스에서 재정의한 equals가 하위 클래스에도 딱 들어맞는다. 클래스가 private이거나 package-private이고 equals 메서드를 호출할 일이 없다. 🤔 equals를 재정의해야 할 때는 언제일까? 객체 식별성(두 객체가 물리적으로 같은가)을 확인하는 것이 아니라 논리적 동치성을 확인해야 하는데, equals가 논리적 동치성을 비교하도록 재정의되지 않았을 때 주로 값 클래스들이 이 경우에 해당한다. (ex. Integer, String) 😁 Equals 메서드를 재정의할 때의 규약 1. 반사성 (Reflexivity) null이 아닌 모든 참조 값 x에..
[JAVA] LinkedHashMap의 방어적 복사 Map.copyOf() 와 Collections.unmodifiableMap() 우아한 테크코스에서 블랙잭 미션을 하다가 입력된 Player들의 순서대로 결과를 보여주고 싶어서 LinkedHashMap으로 Player의 이름과 게임 결과를 묶어서 전달해주었다. 게임 결과를 계산하고 저장하는 객체에서 외부에서 게임 결과를 요청받았을 때 LinkedHashMap을 넘겨주도록 했는데 내부에 저장된 요소를 수정하지 못하도록 방어적 복사를 해서 넘겨주려고 Map.copyOf()를 사용했다. 그런데 최종 결과를 출력할 때 Player들의 순서를 보장해주지 않는 문제가 발생했다. 아마도 Map.copyOf() 메서드가 LinkedHashMap()처럼 순서를 보장해주지 않는 것으로 보였다. 이전 미션 때 '정말 간편한..
[Effective Java] 상속보다는 컴포지션을 사용하라 🤔 상속은 왜 사용하는 거지? 이미 만들어져 있는 클래스를 재사용할 수 있기 때문에 효율적이고 중복된 코드가 줄어들어 코드가 간결해진다. 공통적인 기능을 부모 클래스에 추가해주면 상속받은 여러 개의 자식 클래스에서 사용이 가능하기 때문에 확장성 또한 용이하다. 🧐 상속의 종류 구현 상속 (클래스 상속) 예시 코드 public class SimpleList { String[] simpleList; int size; SimpleList() { simpleList = new String[10]; size = 0; } void add(String value) { simpleArrayList[size] = value; size += 1; } } public class SimpleArrayList extends S..