회고록 블로그
[공부 필기] Java 기본 공부하기 (26) 본문
공부 중인 강의 : 윤성우 선생님, 윤성우의 열혈 Java 프로그래밍 강의.
링크 : https://cafe.naver.com/cstudyjava
1.Object 클래스의 finalize 메소드
- 프로그래머는 잘 쓰지 않는 메소드이고 JVM이 많이 사용하는 메소드임
→ 가비지 컬렉션될 때 자동으로 호출되는 메소드임
→ 좀 더 쉽게 말하면 인스턴스 소멸 시 자동으로 호출되는 메소드임
- 따라서 finalize 메소드를 자식클래스에서 오버라이딩해서 [인스턴스 소멸 시에 수행하고 싶은 코드]를 담아놓을 수도 있음
# 가비지 컬렉션의 과정 복습
- JVM이 가비지 컬렉션을 자주하면 힙 영역에 사용할 수 있는 공간이 널널해짐
- 다만 가비지 컬렉션을 자주하면 프로그램의 속도가 느려지게 됨
→ 따라서 가비지 컬렉션은 [적당히] 하는 것이 좋음
→ 그리고 JVM이 적당한 알고리즘을 통해 가비지 컬렉션을 적당히해줌
→ 여기에서 "적당히"란, 힙 공간이 견딜 수 있고 + 프로그램의 성능에 큰 영향을 주지 않는 정도를 말함
- 가비지 컬렉션은 아래와 같은 과정을 거침
→ 일단 JVM이 힙 영역을 쭉 훑으며 가비지 컬렉션 대상이 있는지 찾음
→ 대상을 찾게 되면 표식(체크 등)을 남겨놓음
→ 만약 프로그램 실행에 있어서 여유가 없다면
가비지 컬렉션 작업은 여기에서 잠시 멈춰두고, 프로그램을 먼저 이어서 실행시킴(프로그램 실행하는데 CPU를 양보함)
→ 중간에 여유가 좀 생기면 체크 해놓은 대상들을 삭제해줌
- 따라서 가비지 컬렉션 과정은 두 단계로 나뉠 수도 있음
→ 여유가 있다면 1)대상을 찾아 체크하기, 2)체크된 대상 삭제하기를 연결해서 처리하겠지만
→ 여유가 없다면 1)번만 먼저 처리해놓고 여유가 생겼을 때 2)번을 처리함
→ 왜냐하면 가비지 컬렉션을 실행하기 위해서는 JVM이 관리하는 프로그램들의 실행을 멈춰야하기 때문
(사실, 메모리의 저장된 많은 객체들이 스캔+삭제되어야하니 프로그램의 실행을 멈추는건 당연함)
##
- finalize 메소드는 "1)가비지 컬렉션 대상을 찾아 체크할 때" 호출되는 것이 아니라 "2)체크된 대상을 삭제할 때" 호출된다는 점 유의
→ 그래서 정확하게 finalize 메소드가 호출되는 시점을 유추하기 어려움
(JVM이 언제 가비지 컬렉션을 수행하는지 정확하게 알기 어렵기 때문)
→ finalize 메소드가 호출되지 않고 프로그램이 종료될 수도 있음
* 만약 힙 영역의 공간이 널널한 상태에서 프로그램이 종료된다면
JVM은 굳이 가비지 컬렉션을 수행한 후 프로그램을 종료하지 않음 (프로그램이 종료되면 힙의 공간이 통째로 비워지기 때문)
→ 그래서 프로그래머 입장에서 이 메소드를 적극적으로 사용하기가 곤란함
(확신할 수 없는 메소드를 얼마나 적극적으로 사용할 수 있겠는가..)
# 참고사항으로 알아둘 점
- 임의의 메소드를 자식클래스에서 오버라이딩해서 사용한다고 가정(finalize 메소드 등)
- 이때 부모클래스의 해당 메소드에 (예상치 못한) 어떤 중요한 코드가 포함되어 있을 수 있음
- 그러므로 오버라이딩 할 땐 부모클래스의 메소드 코드를 함부로 무시해서는 안됨
- 더구나 Object 클래스 같은 경우 모든 객체의 부모클래스로 중요한 코드가 있을 수 있음
- 부모클래스의 메소드 코드를 읽었을 때, 정체를 잘 모르겠지만 어쨌든 메소드 오버라이딩을 반드시 해야하는 상황이라면
super 키워드를 통해 부모클래스의 메소드를 호출하는것도 괜찮은 방법일 수 있음
...
@Override
protected void finalize() {
super.finalize();
...
}
##
2. 가비지 컬렉션 수행 요청 코드
- 보통 JVM이 자동으로 가비지 컬레션 작업을 수행하지만 프로그래머가 JVM에게 가비지 컬렉션을 요청(?)할 수도 있음
- 코드는 아래와 같음
→ 하지만 보통 프로그래머가 가비지 컬렉션 요청을 호출하는 경우는 별로 없다고 함
System.gc(); // 가비지 컬렉션 대상을 찾아 체크(mark)해달라는 요청
System.runFinalization(); // 체크(mark)한 대상을 삭제해달라는 요청
- 코드를 넣었다고 하더라도 그 코드를 읽은 순간에 100% 가비지 컬렉션을 수행한다고 보장할 수는 없음
→ [요청]일 뿐이지 수행 [명령]이 아니기 때문
3. equals 메소드
- equals와 "=="의 차이
→ equals 메소드와 == 연산자는 모두 참조값을 비교한다는 공통점이 있음
→ 다른 점이 있다면, equals 메소드는 오버라이딩해서 사용할 수 있음
- 예시 코드
→ "[obj1]은 [obj2]와 동일한가"에 대해서 묻는 코드
→ 결과는 "False"
* obj1과 obj2가 가리키는 인스턴스가 다르기 때문
(두 객체에 저장되어 있는 값이 동일하더라도 각각 인스턴스를 생성했기 때문에 다른 참조값 가리킴)
Object obj1 = new Object();
Object obj2 = new Object();
if(obj1.equals(obj2))
System.out.println("Same");
else
System.out.println("Not Same");
- equals 메소드 오버라이딩 예시
- String 클래스의 equals 메소드
→ String 역시 Object의 자식클래스이기 때문에 equals 메소드를 사용하고 있음
→ 다만 String 클래스 내부에서 equals 메소드를 오버라이딩 이미 해놓음
→ String 클래스의 equals 메소드는 "두 인스턴스의 내용을 비교하도록" 오버라이딩이 되어있음
- String 인스턴스의 equals 메소드 예시
4. clone 메소드
- 역시나 Object 클래스에 정의되어 있는 메소드임
- 일단 하는 기능은 "대상과 (완전히) 똑같은 인스턴스를 복사"하는 기능을 함
- 임의의 클래스를 복사하기 때문에 clone 메소드의 반환형은 Object임
Object obj1 = new Object();
Ojbect obj2 = obj1.clone(); // 이 자리에는 "복사된 인스턴스의 참조값"이 반환됨
- 사실 인스턴스를 복사하는 것은 조금 주의가 필요함
- 그렇기 때문에 Java에서는 clone 메소드 호출을 허용하려면 프로그래머가 "Cloneable 인터페이스"를 구현해야함
→ Cloneable 인터페이스를 구현한다는 것은 "clone 메소드 호출을 허용한다"는 의미를 담고 있음
→ [주의] Cloneable 인터페이스에 clone 메소드가 선언되어 있다는 의미가 아님
* Cloneable 인터페이스는 마커 인터페이스임(추상 메소드/몸체가 없는 인터페이스)
→ [주의] Cloneable 인터페이스를 구현하지 않는다고해서 clone 메소드가 메모리에 없다는 뜻도 아님
(모든 객체는 Object 클래스를 상속하며, clone 메소드는 Object 클래스의 메소드이기 때문)
→ 다만 clone 메소드를 호출하려면 Cloneable 인터페이스를 구현해야함
- 코드 예시
→ clone 메소드의 접근수준 지시자는 기본적으로 protected인데, 그대로 두면 외부에서 사용할 수가 없음
→ 따라서 오버라이딩 해야함
- 반환형이 Object이기 때문에 참조타입을 Fish형으로 하는 경우 형변환이 필요함
# 참고사항. 메소드 오버라이딩
- [오버라이딩]은 반드시 '동작 방법'을 변경/수정해야만 사용할 수 있는 것은 아님
- 접근수준 지시자를 넓힐 때도 사용할 수 있음
- 예시
...
@Override
public Object clone() throws CloneNotSupportedException {
// protected인 접근수준 지시자를 public으로 넓히고 있음
return super.clone(); // 부모클래스의 clone 기능을 그대로 return할 뿐 변경된 사항은 없음
}
...
- 다만, public을 private으로 변경하는 것은 불가능하고(=좁히는 것은 불가능)
private을 public으로 변경하는 것은 가능함(=넓히는 것은 가능)
##
'2. 프로그래밍 언어 공부 > Java' 카테고리의 다른 글
[공부 필기] Java 기본 공부하기 (27) (0) | 2021.12.06 |
---|---|
[Java 공부하기] clone 메소드를 오버라이딩 해서 사용해야하는 이유에 대해서 찾아보기 (0) | 2021.12.06 |
[공부 필기] Java 기본 공부하기 (25) (0) | 2021.12.01 |
[공부 필기] Java 기본 공부하기 (24) (0) | 2021.12.01 |
[공부 필기] Java 기본 공부하기 (23) (0) | 2021.11.30 |