WeakRef 클래스
WeakRef 클래스
WeakRef는 참조하는 객체가 가비지 컬렉션(GC)의 대상이 될 수 있게 해주는 약한 참조(weak reference) 클래스예요. 일반 참조는 객체가 살아 있는 동안 GC가 그것을 회수하지 못하게 하지만, 약한 참조는 GC가 해당 객체를 회수해도 괜찮아요. 객체 수명에 대해 "내가 참조하고 있지만, 굳이 메모리에 붙잡아 두지는 않겠다"는 트레이드오프가 필요한 캐시 같은 곳에서 유용하죠.
본문
WeakRef는 참조 대상 객체처럼 거의 그대로 사용할 수 있어요. 참조하는 객체에 메서드를 호출하면 내부적으로 위임(delegate)해서 처리해 주거든요.
foo = Object.new # 새 객체 인스턴스를 만들고
p foo.to_s # 원본 클래스의 메서드를 호출
foo = WeakRef.new(foo) # foo를 WeakRef 인스턴스로 재할당
p foo.to_s # 여전히 같은 클래스처럼 동작
GC.start # 가비지 컬렉터를 실행
p foo.to_s # 객체가 회수됐다면 예외가 발생
여기서 주의할 점이 하나 있어요. GC.start를 호출한 뒤에는 원본 객체가 회수될 수 있고, 그 상태에서 메서드를 호출하면 WeakRef::RefError가 발생할 수 있어요. 아직 살아 있는지는 weakref_alive?로 확인할 수 있어요.
상수 (Constants)
VERSION
WeakRef의 버전 문자열이에요.
Public Class Methods
new(orig)
orig에 대한 약한 참조를 만들어요. 참조 대상이 true, false, nil 같은 즉시 값(immediate value)인 경우에는 예외적으로 강한 참조로 보관해요. 그 외에는 내부 맵에 객체를 등록해 두고, Delegator의 생성자를 호출해 위임 기반을 마련해요.
# File lib/weakref.rb, line 35
def initialize(orig)
case orig
when true, false, nil
@delegate_sd_obj = orig
else
@@__map[self] = orig
end
super
end
Public Instance Methods
weakref_alive?()
참조하는 객체가 아직 살아 있는지 true/false로 돌려줘요. 이 메서드가 false를 반환한다면 객체가 회수된 상태라서, 이후 메서드 호출은 실패할 수 있어요.
# File lib/weakref.rb, line 56
def weakref_alive?
@@__map.key?(self) or defined?(@delegate_sd_obj)
end