虚拟机参数:SoftRefLRUPolicyMSPerMB
-XX:SoftRefLRUPolicyMSPerMB从名字看不出什么意思?【官文解读】
- SoftRefLRUPolicyMSPerMB 该参数得官方解释:
What determines when softly referenced objects are flushed?Starting with 1.3.1, softly reachable objects will remain alive for some amount of time after the last time they were referenced.
The default value is one second of lifetime per free megabyte in the heap. This value can be adjusted using the
-XX:SoftRefLRUPolicyMSPerMB flag, which accepts integer values representing milliseconds.
For example, to change the value from one second to 2.5 seconds, use this flag:-XX:SoftRefLRUPolicyMSPerMB=2500
The Java HotSpot Server VM uses the maximum possible heap size (as set with the -Xmx option) to calculate free space remaining.The Java Hotspot Client VM uses the current heap size to calculate the free space.This means that the general tendency is for the Server VM to grow the heap rather than flush soft references, and -Xmx therefore has a significant effect on when soft references are garbage collected.
On the other hand, the Client VM will have a greater tendency to flush soft references rather than grow the heap.The behavior described above is true for 1.3.1 through Java SE 6 versions of the Java HotSpot VMs. This behavior is not part of the VM specification, however, and is subject to change in future releases.
Likewise the -XX:SoftRefLRUPolicyMSPerMB flag is not guaranteed to be present in any given release.
比较好的一个解释:
当gc执行时,决定SoftReference回收有两个因素:
[list]
[]SoftReference的timestamp
[]有多少空闲空间
[/list]
在server模式下,会用-Xmx参数得到空闲空间大小。
在client模式下,会用当前heap最大空闲空间大小。
简单来说,server模式下会优先扩大heap大小,client模式下会优先回收垃圾。SoftReference类中,有一个timestamp:
public class SoftReference<T> extends Reference<T> { /* Timestamp clock, updated by the garbage collector */ static private long clock; /* Timestamp updated by each invocation of the get >method. The VM may use * this field when selecting soft references to be >cleared, but it is not * required to do so. */ private long timestamp; ...... }
在新建SoftReference对象和调用SoftReference.get时都会使>timestamp更新为clock的值。而clock代表的是上次gc的时间。
SoftRefLRUPolicyMSPerMB默认为1000,即1s。代表每1MB>空闲空间大小SoftReference保留1s。
是否回收的条件:
clock - timestamp <= freespace * >SoftRefLRUPolicyMSPerMB举例来说,clock为1000,timestamp为300,空闲空间为1MB。
1000 - 300 <= 1000 * 1
所以不会被回收。【注:当上面条件满足则不会被回收】
一个值得注意的地方是,SoftReference会至少经历1次gc而不被回收。
参考http://jeremymanson.blogspot.com/2009/07/how-hotspot-decides-to->clear_07.html
解释: 我们知道软引用,实在空间不足的情况下才会被回收,当然这个只是一个比较简单的解释。实际上软引用的回收机制复杂得多,需要SoftRefLRUPolicyMSPerMB的意思,就先明白soft-reference在代码逻辑上需要满足的条件是什么,如下:
clock - timestamp <= freespace * SoftRefLRUPolicyMSPerMB
clock记录是上一次GC的时间戳,timestamp则是最近一次读取soft-reference引用对象(即最近调用get())的时间戳。他们的差【clock - timestamp】表示了soft-reference有多久没用了,越大表示越久没用。如果他们的差为负数,表示刚刚用过。而【freespace * SoftRefLRUPolicyMSPerMB】表示能够VM的忍耐度,VM能够忍耐软引用对象多久没有被回收,而VM的忍耐度从公式可以知道是由VM计算得出的空闲空间大小和用户指定的忍耐度SoftRefLRUPolicyMSPerMB来决定的。
也就是说,如果软引用上次被get()的时间离最近一次GC的时间不会太久远的话就可以不被当前GC回收。
题外话:
不得不吐槽一下SoftRefLRUPolicyMSPerMB这个参数的命名:虽然从名字中我们可以看到LRU算法,也可以看到它与SoftRef的GC有关,还有freespace由多少M空间等寓意,但是单纯看这个变量名确实很难直观的明白这个参数的用处,真是到处坑。