您现在的位置是:主页 > news > wordpress文章链接插件/深圳网站设计十年乐云seo
wordpress文章链接插件/深圳网站设计十年乐云seo
admin2025/4/30 8:44:18【news】
简介wordpress文章链接插件,深圳网站设计十年乐云seo,加油站项目建设背景,培训网络营销机构这是我最近在开发的一个基于客户端发现模式(因为基于服务端发现的都比较多了,consul还做得很好)的服务注册发现框架: https://github.com/leoChaoGlut/ServiceDIscoveryAndRegistry 然后在过程中遇到这样一个问题: 在做client-service-proxy的时候,要实现一个负载均衡算法. 我选…
这是我最近在开发的一个基于客户端发现模式(因为基于服务端发现的都比较多了,consul还做得很好)的服务注册发现框架:
https://github.com/leoChaoGlut/ServiceDIscoveryAndRegistry
然后在过程中遇到这样一个问题:
在做client-service-proxy的时候,要实现一个负载均衡算法.
我选了比较常用的轮询分发算法.
在实现过程中,需要将发送过的相同的host和port缓存下来,以便不要再次分发到相同的节点.如果一个服务的所有节点都发送过了,则会清理缓存,重新轮询.
问题来了,实现缓存,如果直接用new HashSet()这样的方式存储,如果内部的元素一直被引用,和GC Root一直有通路,则该对象不会被GC.
但有时候该对象其实又不会经常被用到,存着还是浪费内存.
所以一般会用SoftReference<Set<T>>软引用方式来做缓存容器.
SoftReference的源码介绍里也有提到,它可以被用作memory-sensitive caches.
问题又来了,SoftReference被GC的情况和想象中不一样!!!!!!!!!!!!!
我在测试的时候,用VisualVM来监控测试程序,当我利用VisualVM手动执行Full GC时,SoftReference竟然没有被GC!!!!!!!!
于是乎我又去看了源码的解释,如下:
All soft references to softly-reachable objects are guaranteed to have been cleared before the virtual machine throws an <code>OutOfMemoryError</code>.
意思是在OOM发生之前,它才会被GC掉,而没有发生OOM之前的GC,是不会将SoftReference的对象GC掉的!
会导致的问题:
SoftReference<Set<String>> recordSetRef = new SoftReference<>(new HashSet<>());//1
Set<String> recordSet = recordSetRef.get();//2
if (recordSet.isEmpty()) {//3. 如果运气非常不好...这里可能会报空指针.因为执行到上面那一句的时候,该线程正好失去CPU时间片,且正好即将发生OOM(正常的GC不会清理SoftReference),则此时recordSet会是null
}
根据Java 内存模型:一个代码块内,如果前后的代码不存在关联关系,则可能会发生指令重排序.(当然,上例中没有出现指令重排序).
当然,一个线程对应一个方法栈,如果两个线程之间的数据没有依赖关系,也是不会发生并发线程安全问题的.
如果要避免这样的情况,可以将该代码块用synchronized包裹起来,如果频繁被调用的话,不建议加锁,应该另辟出路.
因为加了锁,就算当前线程失去时间片,在该线程没有执行完同步块之前,其它线程是无法访问其中的数据的.等到线程重新获得时间片,可以继续执行未执行完的代码.
问题在三到来:也许有人想到了,如果加了同步块,其它线程不能访问其中的内容,那要是GC线程呢?好吧,这我也不知道,等我知道了我再告诉你........
有知道的朋友希望可以解答~谢谢~