약한 참조
Weak reference컴퓨터 프로그래밍에서 약한 참조는 강력한 참조와 달리 참조된 개체를 가비지 컬렉터에 의한 수집으로부터 보호하지 않는 참조입니다.약한 참조에 의해서만 참조되는 오브젝트(즉, 오브젝트에 도달하는 모든 참조 체인에 적어도1개의 약한 참조가 링크로서 포함되어 있다)는 도달 불능으로 간주되어 언제든지 수집될 수 있습니다.일부 가비지 컬렉션 언어에는 버전 7.[2]4 이후 C#, Java, Lisp, OCaml, Perl[1], Python 및 PHP와 같은 다양한 수준의 취약한 참조가 포함되어 있거나 지원됩니다.
사용하다
약한 참조는 여러 가지 일반적인 용도가 있습니다.참조 카운팅 가비지 컬렉션을 사용할 경우 사이클 내의 링크에 대해 약한 참조를 사용함으로써 약한 참조가 참조 사이클을 끊을 수 있습니다.키가 오브젝트(참조)인 관련 배열(매핑, 해시 맵)이 있는 경우(예를 들어 오브젝트에 대한 보조 데이터를 보유하는 경우) 키에 대한 약한 참조를 사용하면 오브젝트가 키로 사용되기 때문에 오브젝트가 존속되는 것을 피할 수 있습니다.옵저버 패턴(특히 이벤트 처리) 등 다른 오브젝트가 등록되어 있는 오브젝트가 있는 경우 강한 참조가 유지되면 오브젝트를 명시적으로 등록 해제해야 합니다.그렇지 않으면 메모리누전(리스너 정지 문제)이 발생하고 약한 참조는 등록을 해제할 필요가 없습니다.필요에 따라 재작성할 수 있는 캐시된 데이터를 보유할 때 취약한 참조를 통해 캐시를 회수할 수 있으므로 폐기 가능한 메모리를 효과적으로 생성할 수 있습니다.이 마지막 케이스(캐시)는 다른 케이스와 구별됩니다.필요한 경우에만 오브젝트가 가비지 수집되는 것이 좋기 때문에 약한 참조 내에서 보다 세밀한 구분이 필요하기 때문입니다.여기서는 약한 참조의 강력한 형태가 됩니다.대부분의 경우 약한 참조를 직접 사용할 필요가 없습니다. 대신 약한 배열이나 키 또는 값이 약한 참조인 다른 컨테이너를 사용합니다.
가비지 컬렉션
가비지 컬렉션은 사용되지 않는 개체를 정리하는 데 사용되므로 메모리 누수 및 데이터 손상 가능성을 줄일 수 있습니다.가비지 수집에는 트레이스와 참조 카운트라는 두 가지 주요 유형이 있습니다.참조 카운트 방식은 지정된 객체에 대한 참조 수를 기록하고 참조 카운트가 0이 되면 객체를 수집합니다.참조 카운트는 한 번에 하나의 개체만 수집할 수 있으므로 순환(또는 순환) 참조를 수집할 수 없습니다.따라서 다른 오브젝트에 의해 직접 참조되지 않고 도달할 수 없는 상호 참조 오브젝트 그룹은 영속적으로 상주할 수 있습니다.어플리케이션이 이러한 도달 불가능한 오브젝트 그룹을 지속적으로 생성하면 메모리 누수의 영향을 받습니다.그룹 내 일부 참조에 대해 약한 참조를 사용하여 참조 사이클을 회피할 경우 약한 참조(기준 계수에 포함되지 않는 참조)를 사용하여 순환 참조 문제를 해결할 수 있다.
이러한 강한 기준과 약한 기준의 구별은 문서 객체 모델(DOM)과 같은 트리 구조에서 매우 일반적인 경우로, 부모 대 자식 참조는 강하지만 자식 대 부모 참조는 약하다.예를 들어, 애플의 코코아 프레임워크는 이 접근방식을 권장한다.[3]실제로 오브젝트 그래프가 트리가 아닌 경우에도 트리 구조는 종종 오브젝트 소유의 개념에 의해 강요될 수 있다.여기서 소유 관계가 강하고 트리를 형성하기 위해 비소유 관계가 약하며 트리를 형성하기 위해 필요하지 않다. 이 접근법은 원시 포인터를 약한 참조로 사용하는 C++(C+++11 이전)에서 흔히 볼 수 있다.단, 이 방법에서는 부모 브런치가 삭제 및 삭제되었을 때 검출할 수 없는 단점이 있습니다.C++11 규격 이후, Boost 라이브러리에서 상속된 공유 ptr 및 weak ptr을 사용하여 솔루션이 추가되었습니다.
약한 참조는 또한 프로그램이 약한 참조만을 통해 중요하지 않은 개체를 나타낼 수 있도록 함으로써 메모리 내의 불필요한 개체 수를 최소화하기 위해 사용됩니다.
바리에이션
일부 언어에는 여러 단계의 약한 참조 강도가 있습니다.예를 들어 Java에는 java.lang.[4]ref 패키지에 정의되어 있는 soft, weak 및 pantom 참조가 강도의 감소 순서로 있습니다.각 기준 유형에는 도달 가능성에 대한 관련 개념이 있습니다.GC(Garbage Collector)는 개체의 도달 가능성을 사용하여 개체를 해방할 시기를 결정합니다.GC는 소프트하게 도달할 수 있는 오브젝트를 해방하는 것은 안전하지만 JVM이 메모리를 확보할 수 있다고 판단되면 해방하지 않을 수 있습니다(예를 들어 JVM에는 사용되지 않는 힙 영역이 많이 있습니다).GC는 도달 불능 오브젝트를 검출하면 즉시 해방됩니다.다른 기준 유형과 달리 팬텀 기준은 따를 수 없습니다.한편, 팬텀 참조는 오브젝트가 해방되었을 때 프로그램에 통지하는 메커니즘을 제공합니다(통지는 ReferenceQueues를 사용하여 구현됩니다).
C#에서 약한 참조는 오브젝트 부활을 추적하는지 여부에 따라 구별됩니다.오브젝트에 강한 참조가 있을 경우 오브젝트가 확정되지 않기 때문에 이 구별은 강한 참조에 대해서는 발생하지 않습니다.디폴트로는 C#에서는 부활을 추적하지 않습니다.즉, 오브젝트가 부활해도 약한 참조는 갱신되지 않습니다.이러한 참조를 짧은 약한 참조라고 하며 부활을 추적하는 약한 참조를 긴 [5]약한 참조라고 합니다.
C++와 같이 불필요한 수집이 아닌 일부 언어들은 가비지 수집 라이브러리를 지원하는 일부로서 취약하거나 강력한 참조 기능을 제공합니다.Boost C++ 라이브러리는 강하고 약한 참조를 제공합니다.일반 C++ 포인터를 스마트 포인터의 약한 포인터로 사용하는 것은 실수입니다.이러한 사용으로 인해 강력한 참조 카운트가0이 되어 오브젝트가 삭제되었을 때 검출할 수 없게 되기 때문입니다.게다가 다른 강력한 참조가 이미 주어진 플레인 포인터를 추적하고 있는지 여부를 검출할 수 없습니다.이로 인해 두 개 이상의 스마트 포인터가 동일한 플레인 포인터를 추적할 수 있습니다(이러한 스마트 포인터의 참조 수가 0에 도달하고 개체가 삭제되는 즉시 손상이 발생합니다).
예
취약한 참조는 응용 프로그램에서 참조되는 현재 변수 목록을 유지할 때 유용합니다.이 목록에는 개체에 대한 링크가 약해야 합니다.그렇지 않으면 오브젝트가 목록에 추가되면 오브젝트는 오브젝트에 의해 참조되고 프로그램 기간 동안 유지됩니다.
자바
1998년[6] Java 1.2는 "소프트 레퍼런스"로 알려진 두 가지 종류의 약한 레퍼런스를 도입했습니다. 하나는 "소프트 레퍼런스"(GC 관리 인메모리 캐시 유지에 사용되도록 의도되었지만 Android와 같은[7] 동적 힙을 사용하는 일부 플랫폼에서는 실제로 잘 작동하지 않습니다)와 다른 하나는 단순히 "약한 레퍼런스"입니다.또한 위험하고 비효율적인 finalize()[8] 메커니즘의 대안으로 "phantom references"라고 불리는 관련 실험 메커니즘을 추가했습니다.
취약한 참조가 생성되어 코드의 다른 위치에 있는 경우get()
가비지 수집을 방지할 정도로 약한 참조가 강력하지 않기 때문에 (개체에 대한 강한 참조가 없는 경우) 다음과 같은 경우가 있습니다.get()
갑자기 [9]null을 반환하기 시작합니다.
수입품 java.disc.ref 를 지정합니다.약한 참조; 일반의 학급 레퍼런스 테스트 { 일반의 정적인 무효 주된(스트링[] args) 던지다 중단됨예외. { 약한 참조 r = 신규 약한 참조("나 여기 있어"); StrongReference 시루 = 신규 StrongReference("나 여기 있어"); 시스템..나가..인쇄("gc 이전: r=" + r.얻다() + ", static=" + 시루.얻다()); 시스템..gc(); 실.수면.(100); // r.get()만 늘이 됩니다. 시스템..나가..인쇄("gc 후: r=" + r.얻다() + ", static=" + 시루.얻다()); } }
취약한 참조의 또 다른 용도는 캐시를 쓰는 것입니다.예를 들어 약한 해시 맵을 사용하면 다양한 참조 객체를 약한 참조를 통해 캐시에 저장할 수 있습니다.가비지 컬렉터가 실행되면(예를 들어 응용 프로그램의 메모리 사용량이 충분히 높아지면), 더 이상 다른 개체에 의해 직접 참조되지 않는 캐시된 개체는 캐시에서 제거됩니다.
스몰토크
s1 s2 s1 := '안녕하세요' 알았다.. "강력한 언급이군요" s2 := '세계' 알았다.. "강력한 언급이군요" a := 약한 어레이 포함:s1 포함:s2. a 인쇄일: 성적표. 오브젝트 메모리 collect Garbage(쓰레기 수집). a 인쇄일: 성적표. "두 요소 모두 아직 그곳에 있습니다." s1 := 제로. "강력한 참조가 사라지다" 오브젝트 메모리 collect Garbage(쓰레기 수집). a 인쇄일: 성적표. "첫 번째 요소가 사라졌습니다." s2 := 제로. "강력한 참조가 사라지다" 오브젝트 메모리 collect Garbage(쓰레기 수집). a 인쇄일: 성적표. "두 번째 요소가 사라졌습니다."
루아
약한 테이블 = 설정 가능한({}, {__모드="v"}) 약한 테이블.아이템 = {} 인쇄물(약한 테이블.아이템) 집진 쓰레기() 인쇄물(약한 테이블.아이템)
목표-C 2.0
Objective-C 2.0에서는 가비지 수집뿐만 아니라 자동 참조 카운트도 취약한 참조의 영향을 받습니다.다음 예의 모든 변수와 속성은 약합니다.
@interface WeakRef : NSObject { _ _ weak NSString *str1 ; _ unsafe _ unretained NSString *str2 ; } @property (비원자성, 취약) NSString *str3 ; @property (비원자성, 안전하지 않음) NSStr4 ; @end
의 차이점weak
(__weak
)와unsafe_unretained
(__unsafe_unretained
)는 변수가 가리키는 객체가 할당 해제될 때 변수 값이 변경되는지 여부를 나타냅니다. weak
및 에 갱신됩니다.unsafe_unretained
하나는 흔들림 포인터로 변경되지 않습니다.그weak
참조는 Xcode 4.1(iOS의 경우 4.2)과 함께 Mac OS X 10.7 "Lion" 및 iOS 5 이후 ARC를 사용하는 경우에만 Objective-C에 추가되었습니다.이전 버전의 Mac OS X, iOS 및 GNUstep만 지원unsafe_unretained
약한 것으로 간주합니다.
바라
학급 노드 { 일반의 약한 노드 프리브; // 이중 링크된 목록의 노드 간에 순환 참조를 피하기 위해 약한 참조가 사용됨 일반의 노드 다음 분.; }
파이썬
>>> Import weakref >> Import gc >> 클래스 Egg: ...def 스팸(셀프): ... print()나 살아있어!)>> obj = Egg() >> weak_obj = weakref.ref(obj) >> weak_obj spam() 살아있다!>>> obj = "Something other" >>> gc.collect() 35 >> weak_objspam() 트레이스백(최신 콜의 마지막):<module> AttributeError: 'NoneType' 객체의 파일 "<stdin>", 줄 1: 'spam' 속성이 없습니다.
「 」를 참조해 주세요.
레퍼런스
- ^ 8.8. weakref - 취약한 참조, Python Standard 라이브러리
- ^ "PHP: WeakReference - Manual".
- ^ "Practical Memory Management". developer.apple.com.
- ^ Nicholas, Ethan (May 4, 2006). "Understanding Weak References". java.net. Archived from the original on 2011-03-03. Retrieved October 1, 2010.
- ^ Goldshtein, Zurbalev & Flatow 2012, 페이지 131.
- ^ "WeakReference (Java Platform SE 7 )". docs.oracle.com.
- ^ "SoftReference - Android Developers". developer.android.com.
- ^ "PhantomReference (Java Platform SE 7 )". docs.oracle.com.
- ^ https://web.archive.org/web/20110303225354/http://weblogs.java.net/blog/2006/05/04/understanding-weak-references Java의 예
- Goldshtein, Sasha; Zurbalev, Dima; Flatow, Ido (2012). Pro .NET Performance: Optimize Your C# Applications. Apress. ISBN 978-1-4302-4458-5.
외부 링크
C++
- C++11 표준 라이브러리: 참조
- Boost 1.59 (C++ 라이브러리): 레퍼런스
자바
- Java 개발자 문서: '참조 개체 및 가비지 컬렉션'
- Nicholas, Ethan (May 4, 2006). "Understanding Weak References". java.net. Archived from the original on 2011-03-03. Retrieved October 1, 2010.
- RCache - 취약/소프트 참조 기반 캐시용 Java 라이브러리
- Java 이론 및 실천:메모리 누전 방지(레퍼런스가 약한 경우)
PHP
파이썬
- https://docs.python.org/3/library/weakref.html
- Fred L. Drake, Jr., PEP 205: Weak References, Python Enhancement Proposal, 2001년 1월