b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

softreference_weakreference 用法_referencequeue作用

电脑杂谈  发布时间:2017-05-28 02:01:00  来源:网络整理
softreferencesoftreference

分类:----2.1.1.javaSE----2.1.4.JMM----2.1.3.JVM--14.3.并发--14.1.计算机原理

这是我最近在开发的一个基于客户端发现模式(因为基于服务端发现的都比较多了,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 havebeen 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线程呢?好吧,这我也不知道,等我知道了我再告诉你........

有知道的朋友希望可以解答~谢谢~


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/ruanjian/article-49629-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...