LruCache 의 원리 와 사용
우선 캐 시 의 관건 적 인 절차 로 보고 저장,읽 기,청소 합 니 다.저장 과 읽 기의 차이 가 크 지 않 습 니 다.Lru 알고리즘 은 캐 시 를 만 드 는 것 과 일반적인 데이터 구 조 를 캐 시 하 는 것 이 가장 큰 차이 점 은 청소 정책 에 대한 처리 입 니 다.공간의 제한 으로 인해 모든 캐 시 는 청소 정책 이 필요 합 니 다.가장 간단 한 청소 정책 은 기한 이 지난 시간 과 최대 공간 을 정 하 는 것 입 니 다.최대 사용 공간 을 초과 하여 청소 절차 에 들 어가 야 합 니 다.또한 만 료 시간 이 지난 캐 시 내용 은 만 료 로 표시 되 어 청소 절차 에 들 어가 기 때문에 시간 필드 와 공간 최대 치 를 유지 해 야 합 니 다.물론 완벽 한 캐 시 를 실현 할 수 있 습 니 다.Lru 캐 시가 간단 한 점 은 그 가 만 료 된 시간 을 스스로 유지 하지 않 고 최대 공간 값 만 필요 하 다 는 것 이다.일부 데이터 구 조 를 통 해 매번 캐 시가 명중 되 거나 새로 추 가 된 데 이 터 를 교묘 하 게 맨 앞 에 놓 고 뒤의 데 이 터 는 장시간 사용 하지 않 은 데이터 로 침전 시 키 는 것 이 간단 하 다.그러나 맞 춤 형 과 유연성 이 비교적 떨 어 질 것 이다.예 를 들 어 이 공간의 최대 치 는 max Size 가 얼마나 정 하 느 냐 가 관건 이다.만약 에 너무 작고 데이터 의 양 이 많 으 면 이 lru 알고리즘 은 의 미 를 잃 게 된다.삭 제 될 수 있 는 데이터 도 얼마 전에 방 문 했 기 때문에 max Size 가 너무 크게 정 해 지면 공간 에 낭 비 를 초래 할 수 있다.개인 적 으로 일반적인 방법 보다 가장 큰 공간 이 작 을 것 이 라 고 생각 합 니 다.일반적인 방법 으로 가장 큰 공간 을 출발 할 때 많은 공간 을 차지 한 것 이 분명 합 니 다.그렇지 않 으 면 시간 을 사용 하여 관리 하면 조건 을 만족 시 킬 수 있 습 니 다.
LruCache 는 핫 이 슈 캐 시 에 대한 장점 이 비교적 크 고 일부 자주 여러 번 사용 하 는 데 이 터 는 효율 이 높다.예 를 들 어 이미지 캐 시,일부 첫 페이지 와 같은 그림 은 빈번 할 것 이다.두 번 째 페이지 의 우선 순위 가 높 지 않 으 면 이런 장면 이 비교적 적합 하 다.그러나 우발 적 으로 흩 어 진 데 이 터 는 주기 적 인 데이터 가 현저히 적합 하지 않다.
android sdk lrucache 원리
주로 LinkedHashMap 이라는 데이터 구 조 를 사 용 했 습 니 다.그 는 방문 순 서 를 사용 하여 데 이 터 를 저장 할 수 있 습 니 다.매번 put 와 get 데 이 터 를 사용 할 때 새로운 데 이 터 를 양 방향 링크 의 끝 에 놓 고 읽 기 편 하 며 자주 사용 하지 않 는 것 은 머리 에 점점 가 라 앉 습 니 다.
public final V put(K key, V value) {
if (key == null || value == null) {
throw new NullPointerException("key == null || value == null");
}
V previous;
synchronized (this) {
//put , get 。
putCount++;
//size , sizeOf(key,value) , 1。
size += safeSizeOf(key, value);
previous = map.put(key, value);
if (previous != null) {
// , size
size -= safeSizeOf(key, previous);
}
}
if (previous != null) {
// , , 。
entryRemoved(false, key, previous, value);
}
//
trimToSize(maxSize);
return previous;
}
private int safeSizeOf(K key, V value) {
// sizeOf
int result = sizeOf(key, value);
if (result < 0) {
throw new IllegalStateException("Negative size: " + key + "=" + value);
}
return result;
}
/**
* key value size, , 1
*/
protected int sizeOf(K key, V value) {
return 1;
}
/**
* size
*/
public synchronized final int size() {
return size;
}
public final V get(K key) {
if (key == null) {
throw new NullPointerException("key == null");
}
V mapValue;
synchronized (this) {
mapValue = map.get(key);
if (mapValue != null) {
//get , get 。
hitCount++;
return mapValue;
}
missCount++;
}
/* , ~
* Attempt to create a value. This may take a long time, and the map
* may be different when create() returns. If a conflicting value was
* added to the map while create() was working, we leave that value in
* the map and release the created value.
* create , 。
*/
V createdValue = create(key);
if (createdValue == null) {
return null;
}
synchronized (this) {
createCount++;
// create , key , key create
mapValue = map.put(key, createdValue);
// create , put key , , put
if (mapValue != null) {
// There was a conflict so undo that last put
map.put(key, mapValue);
} else {
size += safeSizeOf(key, createdValue);
}
}
if (mapValue != null) {
// get
entryRemoved(false, key, createdValue, mapValue);
return mapValue;
} else {
//
trimToSize(maxSize);
return createdValue;
}
}
protected V create(K key) {
return null;
}
// maxSize
private void trimToSize(int maxSize) {
while (true) {
K key;
V value;
synchronized (this) {
if (size < 0 || (map.isEmpty() && size != 0)) {
throw new IllegalStateException(getClass().getName()
+ ".sizeOf() is reporting inconsistent results!");
}
if (size <= maxSize) {
break;
}
// BEGIN LAYOUTLIB CHANGE
// get the last item in the linked list.
// This is not efficient, the goal here is to minimize the changes
// compared to the platform version.
Map.Entry<K, V> toEvict = null;
for (Map.Entry<K, V> entry : map.entrySet()) {
toEvict = entry;
}
// END LAYOUTLIB CHANGE
if (toEvict == null) {
break;
}
key = toEvict.getKey();
value = toEvict.getValue();
map.remove(key);
size -= safeSizeOf(key, value);
evictionCount++;
}
entryRemoved(true, key, value, null);
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.