Closed zt9788 closed 11 months ago
简单看了一下,有几个问题需要讨论一下:
简单看了一下,有几个问题需要讨论一下:
- CacheContext是否需要修改?CacheThreadLocal是个很轻量的对象,每个虚拟线程一个,每次new一个出来,问题不大。
- 不能只改你要用到的部分,如果kryo5 encoder/decoder 改了,那么java/kryo encoder/decoder也应该修改
- kryo5 encoder/decoder现在的改法需要讨论。如果虚拟线程每次都new一个出来,那么放在ThreadLocal上面的缓存对象不会有像样的的命中率。kryo对象创建开销还挺大的,outputstream里面的byte[]也不小。是不是应该做个简单的对象池(自己做不要有依赖)
开始也考虑对象池,考虑到复杂度增加,就先用弱引用来实现了 目前看jackson/log4j2的方案,基本是引入无锁对象池, 目前看用的比较多的有jctool的MpmcAtomicArrayQueue,自己写一个也可以(或者分2个阶段来修改?)
我回头先把2改了 对象池的我参考一下,晚一点先简单实现一个
用ArrayBlockingQueue做了一个简单对象池,是否可行? 如果可行,我就用这个把2,3重新改一下
public class ObjectPool<T> {
private final ArrayBlockingQueue<T> queue;
private final int size;
private final ObjectFactory<T> factory;
public ObjectPool(int size, ObjectFactory<T> factory) {
this.size = size;
this.factory = factory;
queue = new ArrayBlockingQueue<>(size);
for (int i = 0; i < size; i++) {
queue.add(factory.create());
}
}
public T borrowObject() {
T t = queue.poll();
if(t == null)
return factory.create();
return t;
}
public void returnObject(T obj) {
if (obj == null) {
return;
}
queue.offer(obj);
factory.reset(obj);
}
public interface ObjectFactory<T> {
T create();
void reset(T obj);
}
}
简单看了一下,有几个问题需要讨论一下:
- CacheContext是否需要修改?CacheThreadLocal是个很轻量的对象,每个虚拟线程一个,每次new一个出来,问题不大。
- 不能只改你要用到的部分,如果kryo5 encoder/decoder 改了,那么java/kryo encoder/decoder也应该修改
- kryo5 encoder/decoder现在的改法需要讨论。如果虚拟线程每次都new一个出来,那么放在ThreadLocal上面的缓存对象不会有像样的的命中率。kryo对象创建开销还挺大的,outputstream里面的byte[]也不小。是不是应该做个简单的对象池(自己做不要有依赖)
- 不清除理论上也可以,只是会极大的延长ThreadLocal生命周期,造成少量的内存浪费
- 我再看一下,可能改漏了
- 开始也考虑对象池,考虑到复杂度增加,就先用弱引用来实现了 目前看jackson/log4j2的方案,基本是引入无锁对象池, 目前看用的比较多的有jctool的MpmcAtomicArrayQueue,自己写一个也可以(或者分2个阶段来修改?) 我回头先把2改了 对象池的我参考一下,晚一点先简单实现一个
1 按我的理解,虚拟线程结束的时候,它的ThreadLocal会被gc吧。如果是这样,多个CacheThreadLoca好像问题不大?最多几十个字节。
用ArrayBlockingQueue做了一个简单对象池,是否可行? 如果可行,我就用这个把2,3重新改一下
public class ObjectPool<T> { private final ArrayBlockingQueue<T> queue; private final int size; private final ObjectFactory<T> factory; public ObjectPool(int size, ObjectFactory<T> factory) { this.size = size; this.factory = factory; queue = new ArrayBlockingQueue<>(size); for (int i = 0; i < size; i++) { queue.add(factory.create()); } } public T borrowObject() { T t = queue.poll(); if(t == null) return factory.create(); return t; } public void returnObject(T obj) { if (obj == null) { return; } queue.offer(obj); factory.reset(obj); } public interface ObjectFactory<T> { T create(); void reset(T obj); } }
简单来说,这样就可以了。
pool不能自动缩小的问题,就像以前output里面的字节数组一样,没有简单的好办法,我以前用weak ref,靠ygc来定期清理,也不是很好的方案。
用ArrayBlockingQueue做了一个简单对象池,是否可行? 如果可行,我就用这个把2,3重新改一下
public class ObjectPool<T> { private final ArrayBlockingQueue<T> queue; private final int size; private final ObjectFactory<T> factory; public ObjectPool(int size, ObjectFactory<T> factory) { this.size = size; this.factory = factory; queue = new ArrayBlockingQueue<>(size); for (int i = 0; i < size; i++) { queue.add(factory.create()); } } public T borrowObject() { T t = queue.poll(); if(t == null) return factory.create(); return t; } public void returnObject(T obj) { if (obj == null) { return; } queue.offer(obj); factory.reset(obj); } public interface ObjectFactory<T> { T create(); void reset(T obj); } }
简单来说,这样就可以了。
pool不能自动缩小的问题,就像以前output里面的字节数组一样,没有简单的好办法,我以前用weak ref,靠ygc来定期清理,也不是很好的方案。
OK,我明天按照这个方案再改一下2,3;
CacheThreadLocal确实可以回收,嗯,这块应该影响不大,我还原一下
还有个java encoder/decoder也需要改
这个我合并了,还有一些地方在使用synchronized,你要改吗?
这个我合并了,还有一些地方在使用synchronized,你要改吗?
我之前主要看了core. 那就我改吧 ,不过要下周预计周二、周三的样子
大量虚拟线程下ThreadLocal可能内存泄漏 缓存类型先用weak处理