자바 의 인용 유형 및 사용 장면 을 자세히 설명 합 니 다.
1.강 인용(강 참조)
강 한 인용 유형 은 우리 가 가장 자주 말 하 는 유형 입 니 다.우 리 는 먼저 예 를 보 겠 습 니 다.
package cn.bridgeli.demo.reference;
/**
* @author BridgeLi
* @date 2021/2/26 10:02
*/
public class User {
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("finalize");
}
}
package cn.bridgeli.demo.reference;
import org.junit.Test;
/**
* @author BridgeLi
* @date 2021/2/26 10:03
*/
public class StrongReferenceTest {
@Test
public void testStrongReference() {
User user = new User();
user = null;
System.gc();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
인 스 턴 스 대상 이 강 한 인용 을 가지 고 있 을 때 쓰레기 수 거 기 는 이 대상 을 회수 하지 않 는 다 는 것 을 잘 알 고 있 습 니 다.메모리 가 부족 할 때 OOM,즉 OutOfmery Error 이상 을 던 져 도 강 한 인용 대상 을 회수 하지 않 습 니 다.JVM 은 강 한 인용 대상 이 사용자 가 사용 하고 있 는 대상 이 라 고 생각 하기 때문에 무엇 을 회수 해 야 하 는 지 분간 할 수 없습니다.강제로 회수 하면 시스템 에 심각 한 오류 가 발생 할 수 있다.그러나 대상 이 null 로 할당 되면 회수 되 고 대상 의 finalize 함 수 를 실행 합 니 다.이때 우 리 는 이 함 수 를 통 해 자신 을 구 할 수 있 습 니 다.그러나 두 가지 주의해 야 할 것 은 한 번 만 구 할 수 있 고 다시 쓰레기 에 회수 되 었 을 때 구 할 수 없습니다.다른 하 나 는 일이 있 으 면 절대 함 수 를 다시 쓰 지 마 세 요.이 예 는 단지 문 제 를 설명 하기 위해 이 함 수 를 다시 썼 을 뿐 입 니 다.만약 에 업무 중 에 이 함 수 를 잘못 다시 썼 다 면 쓰레기 를 회수 하지 못 할 수도 있 습 니 다.결국 OOM,그리고 GC 에 익숙 한 친구 가 있 습 니까?내 가 왜 자야 되 는 지 맞 춰 봐.2.소프트 인용(소프트 참조)
제 가 자바 를 처음 배 웠 을 때 소프트 인용 을 어떻게 사용 하 는 지 몰 랐 습 니 다.그 때 는 강 한 인용 만 알 고 있 었 습 니 다.사실은 자바.lang.ref.SoftReference 류 를 통 해 소프트 인용 을 사 용 했 습 니 다.소프트 인용 을 설명 하기 위해 서 우 리 는 먼저 예 를 보 겠 습 니 다.
package cn.bridgeli.demo.reference;
import org.junit.Test;
import java.lang.ref.SoftReference;
/**
* @author BridgeLi
* @date 2021/2/26 10:21
*/
public class SoftReferenceTest {
@Test
public void testSoftReference() {
SoftReference<byte[]> softReference = new SoftReference<>(new byte[1024 * 1024 * 10]);
System.out.println(softReference.get());
System.gc();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(softReference.get());
byte[] bytes = new byte[1024 * 1024 * 12];
System.out.println(softReference.get());
}
}
get 방법 을 통 해 우리 의 소프트 인용 대상 을 얻 는 것 외 에 실행 결과 와 강 한 인용 유형 은 다 르 지 않 습 니 다.그 렇 죠?결 과 는 우리 가 생각 하 는 것 과 같 지만 조급해 하지 마 세 요.시작 파 라 메 터 를 추가 해서 다시 시도 해 보 세 요.
-Xms20m -Xmx20m
우 리 는 모두 이 두 개의 매개 변 수 는 JVM 이 시 작 될 때 쌓 인 최대 치 와 최소 치 를 제어 하 는 것 임 을 알 고 있 습 니 다.이 안에 우리 가 설정 한 최대 치 와 최소 치 는 모두 20m 입 니 다.강 한 인용 논리 에 따라 우 리 는 모두 22M 의 공간 을 신 청 했 습 니 다.OOM 이 어야 합 니 다.사실은 증명 되 지 않 았 습 니 다.인쇄 문 구 를 통 해 우리 의 소프트 인용 이 회수 되 었 음 을 증명 합 니 다.따라서 소프트 인용 의 특징 은 메모리 가 충분 할 때 소프트 인용 대상 은 쓰레기 회수 기 에 의 해 회수 되 지 않 고 메모리 가 부족 할 때 만 쓰레기 회수 기 는 소프트 인용 대상 을 회수 합 니 다.물론 소프트 인용 대상 을 회수 한 후에 도 충분 한 메모리 가 없 을 때 도 메모리 에 이상 이 발생 합 니 다.소프트 인용의 특징 을 보면 우 리 는 소프트 인용의 사용 장면 인 캐 시 를 쉽게 생각 할 수 있다.처음 일 할 때 한 동료 가 나 에 게 안 드 로 이 드 를 하고 그림 을 불 러 오 는 애플 리 케 이 션 이 있 었 다 고 말 했다.특히 번 거 로 웠 고 OOM 을 할 수 있 었 다.사실은 소프트 인용 을 사용 하면 이 문 제 를 쉽게 해결 할 수 있 을 것 이다.
3.약 인용(Weak Reference)
약 한 인용 은 자바.lang.ref.Weak Reference 류 를 통 해 이 루어 집 니 다.마찬가지 로 우리 도 먼저 예 를 보 겠 습 니 다.
package cn.bridgeli.demo.reference;
import org.junit.Test;
import java.lang.ref.WeakReference;
/**
* @author BridgeLi
* @date 2021/2/26 10:30
*/
public class WeakReferenceTest {
@Test
public void testWeakReference() {
WeakReference<User> weakReference = new WeakReference<>(new User());
System.out.println(weakReference.get());
System.gc();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(weakReference.get());
}
}
예 를 들 어 약 한 인용 은 소프트 인용 보다 약 한 인용 유형 임 을 알 수 있다.시스템 GC 에서 약 한 인용 을 발견 하면 시스템 의 공간 이 충분 하 든 상 관 없 이 대상 을 회수 할 것 이다.여기 서 학생 들 이 의문 이 있 을 수 있 습 니 다.GC 가 언제 시작 되 는 지,우리 가 호출 을 표시 하 는 것 을 제외 하고 우 리 는 통제 할 수 없습니다.(사실은 우리 가 호출 을 표시 하 더 라 도 GC 는 즉시 실행 되 지 않 을 수 있 습 니 다)그리고 GC 이후 에 약 한 인용 은 즉시 회수 되 고 인용 되 지 않 습 니 다.그러면 이 유형 은 무슨 소 용이 있 습 니까?사실 이 유형 은 정말 유용 합 니 다.우리 의 유명한 ThreadLocal 류 는 바로 이런 유형의 도움 을 받 아 이 루어 진 것 입 니 다.그래서 ThreadLocal 을 사용 할 때 약 한 유형 을 사 용 했 습 니 다.저 는 예전 에 ThreadLocal 에 관 한 글 을 쓴 적 이 있 습 니 다.그러나 그 당시 에 이해 가 정확 하지 않 았 지만 설명 하 는 예 는 문제 가 없 었 기 때문에 참고 가치 가 있 습 니 다.나중에 언제 ThreadLocal 에 관 한 글 을 다시 쓸 수 있 는 지 살 펴 보고 이런 종 류 를 자세히 말 해 보 세 요.또한 ThreadLocal 류 를 제외 하고 한 가지 더 말 할 만 한 것 이 있 습 니 다.그것 이 바로 자바 util.Weak HashMap 류 입 니 다.유명한 의 미 를 보면 우 리 는 이러한 특징 을 짐작 할 수 있 습 니 다.마찬가지 로 하나의 예 를 통 해 설명 한다.
package cn.bridgeli.demo.reference;
import org.junit.Test;
import java.util.Map;
import java.util.WeakHashMap;
/**
* @author BridgeLi
* @date 2021/2/26 10:38
*/
public class WeakHashMapTest {
@Test
public void testWeakHashMap() {
Map map = new WeakHashMap<String, Object>();
for (int i = 0; i < 10000; i++) {
map.put("key" + i, new byte[i]);
}
// Map map = new HashMap<String, Object>();
// for (int i = 0; i < 10000; i++) {
// map.put("key" + i, new byte[i]);
// }
}
}
시작 할 때 설정 하고 시작 할 때 쌓 인 크기 를 설정 하 세 요.너무 크게 설정 하지 마 세 요.차이 점 을 볼 수 있 습 니 다.4.거짓 인용(Phantom Reference)
앞의 예 를 통 해 우 리 는 인용 강도 가 점점 약해 지 는 것 을 볼 수 있 습 니 다.그래서 가상 인용 은 가장 약 한 인용 유형 입 니 다.도대체 얼마나 약 한 지 알 수 있 습 니 다.우 리 는 같은 예 를 통 해 알 수 있 듯 이 가상 인용 은 자바.lang.ref.Phantom Reference 류 를 통 해 이 루어 진 것 입 니 다.
package cn.bridgeli.demo.reference;
import org.junit.Test;
import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.util.ArrayList;
import java.util.List;
/**
* @author BridgeLi
* @date 2021/2/26 11:05
*/
public class PhantomReferenceTest {
ReferenceQueue referenceQueue = new ReferenceQueue();
List<Object> list = new ArrayList<>();
@Test
public void testPhantomReference() {
PhantomReference<Object> phantomReference = new PhantomReference<>(new Object(), referenceQueue);
System.out.println(phantomReference.get());
new Thread(() -> {
while (true) {
Reference reference = referenceQueue.poll();
if (null != reference) {
System.out.println("============ " + reference.hashCode() + " ============");
}
}
}).start();
new Thread(() -> {
while (true) {
list.add(new byte[1024 * 1024 * 10]);
}
}).start();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
우리 가 봤 어.뭐야?부 드 러 운 인용 과 약 한 인용 도 약 하지만 우 리 는 get 방법 을 통 해 우리 의 인용 대상 을 얻 을 수 있 습 니 다.그러나 허위 인용 은 안 됩 니 다.소스 코드 를 클릭 하면 허위 인용 get 방법 을 볼 수 있 습 니 다.바로 null 로 돌아 갑 니 다.즉,우 리 는 허위 인용 대상 을 직접 가 져 가지 못 합 니 다.그러면 이 유형 은 어떤 사용 장면 이 있 습 니까?사실 이 유형 은 일반 프로그래머 에 게 사용 되 는 것 이 아니 라 io,쌓 아 올 리 는 메모리 에서 사용 되 기 때문에 일반 프로그래머 에 게 이런 유형 이 존재 한 다 는 것 을 알 게 되 었 습 니 다.또한 위의 예 를 통 해 우 리 는 쓰레기 회수 기 가 대상 을 회수 하려 고 할 때 허위 인용 이 있 는 것 을 발견 하면 쓰레기 를 회수 한 후에이 대상 을 없 애고 이 인용 을 인용 대기 열 에 추가 합 니 다.프로그램 은 인용 대기 열 에 가상 인용 이 추가 되 었 는 지 판단 함으로써 인 용 된 대상 이 쓰레기 로 회수 되 는 지 여 부 를 알 수 있다.그러면 프로그램 에서 인용 대기 열 에 가상 인용 이 추가 되 었 음 을 발견 할 수 있 습 니 다.인용 대상 의 메모리 가 회수 되 기 전에 필요 한 행동 을 취 할 수 있 습 니 다.이상 은 자바 의 인용 유형 과 사용 장면 에 대한 상세 한 내용 입 니 다.자바 인용 유형 과 사용 장면 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 하 세 요!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.