我想了解时钟缓存替换策略的原理。
什么时候开始工作? 我们有例如缓存大小= 5。 因此,首先我们将5个随机对象添加到缓存中。当我认为所有这些对象最初都是clockbit = 0时,我是真的吗? 然后当第六个物体到来时,我们必须为它找到一个地方。 我们应该尝试在没有Clock hand的情况下在缓存中找到相同的对象(只是ifInCache(comingObject))? 如果缓存中没有这样的对象会发生什么? 时钟指针的起始位置在哪里?
我阅读了很多文章,只想了解有关时钟的主要问题。
答案 0 :(得分:4)
当我认为所有这些对象最初都是clockbit = 0时,我是真的吗?
如果没有引用它们,那么是。
我们是否应该尝试在没有Clock hand的情况下在缓存中找到相同的对象(只是ifInCache(comingObject))?
是的,你必须检查对象是否已经在缓存中。如果是,则参考位(clockbit)将设置为1。
如果缓存中没有这样的对象会怎样?时钟指针的起始位置在哪里?
如果对象尚未在缓存中,则在时钟指针处检查对象。手的位置将是缓存中的最后位置(如果它尚未填满),并且在两个缓存查找之间保持相同(它将通过查找本身递增)。
示例(缓存大小= 5):
A
- > B
- > C
- > D
- > E
- > F
- >在0处,检查A
的参考位,如果是0替换并递增指针,否则仅递增指针 - >之后手是1 请注意,如果所有对象的引用位都设置为1,则将更换手中的对象,因为在检查对象后,其引用位设置为0,因此第二次检查对象时该位将为0。
编辑:
这是@PeterLawrey代码的扩展/调整版本:
private final Object[] objects= new Object[5];
private final boolean[] referenced = new boolean[5]; //boolean for simplicity
private int clock = 0;
public Object getOrCache(Object obj) {
for(int i = 0; i < objects.length; ++i) {
if (obj.equals(objects[i])) {
referenced[i] = true; //object has been referenced, note that this is for simplicity and could be optimized
return obj;
}
}
//loop over the entries until there is a non-referenced one
//reference flags are removed in the process
while( referenced[clock] ) {
referenced[clock] = false;
clock = (clock + 1) % objects.length; //for clarity
}
//replace the object at the current clock position and increment clock
objects[clock] = obj;
referenced[clock] = true;
clock = (clock + 1) % objects.length; //for clarity
return obj;
}
答案 1 :(得分:2)
我认为你让自己变得复杂。人们使用这种方法的原因是它非常简单。
这样可以避免更换最近使用的熵。
private final Object[] objects = new Object[5];
private final boolean[] referenced = new boolean[objects.length];
private int clock = 0;
public Object getOrCache(Object obj) {
for (int i = 0, objectsLength = objects.length; i < objectsLength; i++) {
Object o = objects[i];
if (obj.equals(o)) {
referenced[i] = true;
return obj;
}
}
while(referenced[clock]) {
referenced[clock] = false;
incrClock();
}
objects[clock] = obj;
incrClock();
return obj;
}
private void incrClock() {
if (++clock >= objects.length)
clock = 0;
}
这不会打扰。
private final Object[] objects= new Object[5];
private int clock = 0;
public Object getOrCache(Object obj) {
for(Object o: objects)
if (obj.equals(o))
return obj;
objects[clock++ % objects.length] = obj;
return obj;
}