본문 바로가기

전체 글150

[Optimizing Java] 2. JVM 이야기 성능에 관심있는 개발자라면 기본적으로 JVM 기슬 스택의 구조를 이해해야 한다. 이 장에서는 뒷부분에 나오는 고급 주제의 기본 지식을 제공하기 위해 JVM이 자바 코드를 실행하는 방법을 소개한다. 바이트코드에 대하여 9장에서 자세히 다루지만, 먼저 가볍게 읽은 후 9장을 읽을 때 다시 읽어보면 좋음 JVM : 자바를 실행하기 위한 가상 기계 JVM구성요소 자바 인터프리터(interpreter) 클래스 로더(class loader) JIT 컴파일러(Just-In Time compiler) 가비지 컬렉터(garbage collector) 2.1 인터프리팅과 클래스로딩 JVM : 스택 기반의 해석머신, 레지스터(물리적 하드웨어) 없지만 일부 결과를 실행 스택에 보관하며 이 스택의 맨 위 쌓인 값(들)을 가져와.. 2023. 6. 11.
[Optimizing Java] 1. 성능과 최적화 성능 분석은 경험주의(empiricism)와 인간 심리학(human psychology)이 교묘히 어우러진 분야 성능 분석에서 중요한 건 1. 관측지표의 절대 수치 2.엔드유저 3.기타 이해관계자들이 그 수치를 어떻게 받아들이는가 하는 점 이 책에서는 이 뻔한 패러독스를 해결하는 내용을 다룸 1.1 자바 성능 : 잘못된 방법 최신 자바의 가상 디스패치 성능은 엄청나게 좋아졌음 특히 JVM의 자동 인라이닝(automatic managed inlining) 덕분에 가상 디스패치조차 대부분의 호출부(call site)에서 사라졌음 온라인상의 오래된 정보를 그대로 받아들이기 어려운 이유 인라이닝 : 메소드를 상수로 교체하는 것을 메소드 인라이닝(Method Inlining) 따라서 우수한 성능 목표를 달성하기 .. 2023. 6. 4.
[리팩토링] 냄새22,리팩토링42 냄새22. 데이터 클래스(Data Class) 데이터 클래스 : public 필드 또는 필드에 대한 게터와 세터만 있는 클래스 클래스 안에 적절한 메소드 없이 필드만 모여있는 클래스의 냄새 : 코드가 적절한 위치에 있지 않다는 뜻 내포. 클래스 내부에 선언된 필드가 어딘가에서 사용이 될텐데 필드만 있는거라면, 사용되는 부분이 적절한 위치가 아니라는 뜻 코드가 적절한 위치에 있지 않기 때문에 이러한 냄새가 생길 수 있다. 예외적으로 "단계 쪼개기"에서 중간 데이터를 표현하는데 사용할 레코드는 불변 객체로 데이터를 전달하는 용도로 사용할 수 있다. public 필드를 가지고 있다면 "레코드 캡슐화하기 (Encapsulate Record)"를 사용해 게터나 세터를 통해서 접근하도록 고칠 수 있다. 변경되지 않.. 2023. 5. 27.
[리팩토링] 냄새17,리팩토링37 냄새17. 메세지 체인 (Message Chains) 레퍼런스를 따라 계속해서 메소드 호출이 이어지는 코드 예) this.member.getCredit().getLevel().getDescription() 해당 코드의 클라이언트가 코드 체인을 모두 이해해야 한다. 체인 중 일부가 변경된다면 클라이언트의 코드도 변경해야 한다. (getCredit() -> getRange() 메소드로 변한다면 모든 클라이언트 코드 변경 필요) 관련 리팩토링 "위임 숨기기(Hide Delegate)"를 사용해 메시지 체인을 캡슐화할 수 있다. : 클라이언트가 최소의 코드만 알아도 되게 "함수 추출하기(Extract Function)"로 메시지 체인 일부를 함수로 추출한 후 함수 옮기기(Move Functioin)"으로 해당 .. 2023. 5. 21.
[리팩토링] 냄새16,리팩토링36 냄새16. 임시필드(Temporary Field) 클래스에 있는 어떤 필드가 특정한 경우에만 값을 갖는 경우 (ex. null, 기본값, 임의로 정한 임시값 : String 변수의 "empty"로 한다던지) 변수가 임시값(unknown, null)을 가질 때 조건이 추가되어야 한다. 어떤 객체의 필드가 "특정한 경우에만" 값을 가진다는 것을 이해하는 것은 일반적으로 예상하지 못하기 때문에 이해하기 어렵다. 관련 리팩토링 "클래스 추출하기(Extract Class)"를 사용해 해당 변수들을 옮길 수 있다. "함수 옮기기(Move Fuction)"을 사용해서 해당 변수를 사용하는 함수를 특정 클래스로 옮길 수 있다. "특이 케이스 추가하기 (Introduce Special Case)"를 적용해 "특정한 경우.. 2023. 5. 21.
[리팩토링] 리팩토링21~23 리팩토링21. 파생 변수를 질의 함수로 바꾸기 Replace Derived Variable with Query 변경할 수 있는 데이터를 최대한 줄이도록 노력해야 한다. (가급적이면 변경 될 수 있는 변수 줄이기) 계산해서 알아낼 수 있는 변수는 제거할 수 있다. 계산에 필요한 데이터가 변하지 않는 값이라면, 계산의 결과에 해당하는 데이터 역시 불변 데이터기 때문에 해당 변수는 그대로 유지할 수 있다. Ex) discountedTotal : 파생 데이터 (총액 – 할인액) 리팩토링22. 여러 함수를 변환 함수로 묶기 Combine Functions into Transform 관련있는 여러 파생 변수를 만들어내는 함수가 여러곳에서 만들어지고 사용된다면 그러한 파생 변수를 “변환 함수(transform fun.. 2023. 5. 7.
[이펙티브자바] 아이템30. 이왕이면 제네릭 메서드로 만들라 아이템30. 이왕이면 제네릭 메서드로 만들라 핵심정리 매개변수화 타입을 받는 정적 유틸리티 메서드 한정적 와일드카드 타입(아이템 31)을 사용하면 더 유연하게 개선할 수 있다. 컴파일 타입에 타입 안정성 보장 ( 자동으로 런타임때에도 타입 안정성 보장) 메서드에서 사용할 제네릭 타입은 접근지시자와 리턴 타입 사이에 정의 public static Set union(Set s1, Set s2) 제네릭 싱글턴 팩터리 타입이 달라도 하나의 싱글톤 팩터리 메소드를 활용할 수 있다. (소거 방식이기 때문에) 불변 객체 하나를 어떤 타입으로든 매개변수화 할 수 있다. 타입 소거되기 때문에, 같은 메소드인데 타입이 다르다고 해서 새롭게 선언할 필요가 없음 제네릭 타입을 사용하면, 컴파일 후 타입 소거가 되지만 명시적으.. 2023. 4. 8.
[이펙티브자바] 아이템29. 이왕이면 제네릭 타입으로 만들라 아이템29. 이왕이면 제네릭 타입으로 만들라 핵심정리 배열을 사용하는 코드를 제네릭으로 만들 때 해결책 두 가지. (성능 등의 이유로 배열을 사용해야 할 때) 첫번째 방법 : 제네릭 배열(E[]) 대신에 Object 배열을 생성한 뒤에 제네릭 배열로 형변환 한다. 형변환을 배열 생성시 한 번만 한다. 가독성이 좋다. 힙 오염이 발생할 수 있다. 두번째 방법 : 제네릭 배열 대신에 Object 배열을 사용하고, 배열이 반환한 원소를 E로 형변환한다. Object 배열을 사용하기 때문에 힙 오염 발생 안한다. 원소 꺼낼 때마다 형변환을 해줘야하는 점이 단점 예) 스택 : Element 안에 객체가 들어가는 자료구조에서, 런타임시 ClassCastException을 줄이는데 유용 Object 타입을 사용할 때.. 2023. 4. 8.
[이펙티브자바] 아이템25. 톱 레벨 클래스는 한 파일에 하나만 담으라. 아이템25. 톱 레벨 클래스는 한 파일에 하나만 담으라. 핵심정리 한 소스 파일에 톱 레벨 클래스를 여러 개 선언하면 컴파일 순서에 따라 결과가 달라질 수 있다. 다른 클래스에 딸린 부차적인 클래스는 정적 멤버 클래스로 만드는 것이 낫다. 읽기 좋으며(가독성) private으로 선언해서 접근 범위도 최소한으로 관리할 수 있다. 출처 : 백기선님 - 이펙티브 자바 완벽 공략 2부 2023. 4. 2.