SoftReferenceWeakReference区别避免混淆软引用和弱引用的不同从源码注释入手以及手写测试避免记错混淆使用谐音记忆法
简书链接:SoftReferenceWeakReference区别避免混淆软引用和弱引用的不同从源码注释入手以及手写测试避免记错混淆使用谐音记忆法
文章字数:1831,阅读全文大约需要7分钟
我的app很头疼,
有时候很容易记混淆,搞不懂哪个是内存不足才会回收,哪个随时可能被回收 哪个调用gc之后一定会回收,哪个是安卓推荐使用的..
那么先从安卓的源码开始,打开源码发现有一段注释证明软引用不推荐使用,
SoftReference
1 |
- Soft reference objects, which are cleared at the discretion of the garbage
- collector in response to memory demand.
Suppose that the garbage collector determines at a certain point in time
- that an object is softly
- reachable. At that time it may choose to clear atomically all soft
- references to that object and all soft references to any other
- softly-reachable objects from which that object is reachable through a chain
- of strong references. At the same time or at some later time it will
- enqueue those newly-cleared soft references that are registered with
- reference queues.
All soft references to softly-reachable objects are guaranteed to have
- been cleared before the virtual machine throws an
OutOfMemoryError . Otherwise no constraints are placed upon the - time at which a soft reference will be cleared or the order in which a set
- of such references to different objects will be cleared. Virtual machine
- implementations are, however, encouraged to bias against clearing
- recently-created or recently-used soft references.
Avoid Soft References for Caching
- In practice, soft references are inefficient for caching. The runtime doesn’t
- have enough information on which references to clear and which to keep. Most
- fatally, it doesn’t know what to do when given the choice between clearing a
- soft reference and growing the heap.
The lack of information on the value to your application of each reference
- limits the usefulness of soft references. References that are cleared too
- early cause unnecessary work; those that are cleared too late waste memory.
Most applications should use an {@code android.util.LruCache} instead of
- soft references. LruCache has an effective eviction policy and lets the user
- tune how much memory is allotted.
- @author Mark Reinhold
- @since 1.2
*/
1 | 从上面有几个关键英文单词 |
All soft references to softly-reachable objects are guaranteed to have
- been cleared before the virtual machine throws an
OutOfMemoryError. O1
2
3
4
5
6```guaranteed ``` 保证
虚拟机保证在内存不足之前清理所有Soft references,我英语不好,应该是说内存不足的时候才会清除?还是说内存不足的时候一定会清除,但是不足的时候清除不清除呢?
# **WeakReference**
注释:
/**
- Weak reference objects, which do not prevent their referents from being
- made finalizable, finalized, and then reclaimed. Weak references are most
- often used to implement canonicalizing mappings.
Suppose that the garbage collector determines at a certain point in time
- that an object is weakly reachable. At that time it will atomically clear all weak references to
- that object and all weak references to any other weakly-reachable objects
- from which that object is reachable through a chain of strong and soft
- references. At the same time it will declare all of the formerly
- weakly-reachable objects to be finalizable. At the same time or at some
- later time it will enqueue those newly-cleared weak references that are
- registered with reference queues.
*/
1 |
|
Launch configurations for ‘TestReference.java’ ->Argments选项卡 Vm argments里面填写参数-Xmx2m -xms2m
1 |
|
/**
*Launch configurations for 'TestReference.java' ->Argments选项卡 Vm argments里面填写参数-Xmx2m -xms2m
* @param args
*/
public static void main(String[] args) {
Object referent = new Object();
java.util.List<String[]> list = new ArrayList<>();
SoftReference<Object> softRerference = new SoftReference<Object>(referent);
assertNotNull(softRerference.get());
referent = null;
int count = 0;
while (softRerference.get()!=null) {
System.out.println("obj!=null count:" + count);
count++;
String[] current=new String[1000];
System.out.println("isempty:"+(softRerference.get()==null));
list.add(current);
for (int i = 0; i < current.length; i++) {
current[i]=i+"";
}
if(count%1000==0){
}
}
System.out.println("obj is recycle");
/**
* soft references 只有在 jvm OutOfMemory 之前才会被回收, 如果回收后发现还是内存不足,那么蛋蛋了
* Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
at java.util.Arrays.copyOfRange(Arrays.java:3664)
at java.lang.String.<init>(String.java:207)
at java.lang.StringBuilder.toString(StringBuilder.java:407)
at TestReference.main(TestReference.java:29)
*
*/
}
1 |
|
static class MyObj {
public MyObj(int no) {
this.no = no;
}
public String[] getCurrent() {
return current;
}
public void setCurrent(String[] current) {
this.current = current;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
String[] current = new String[1000];
int no;
@Override
protected void finalize() throws Throwable {
System.out.println("from:"+no+" :我被回收了我是hasCode:" + hashCode());
super.finalize();
}
}
1 | ``` |
输出结果:
1 | =================================弱引用测试================================= |
测试调节初始化数组大小为500 或者1000 如果是1千,我们发现即使没有调用System.gc()它已经开始进行回收了,也就是稍微吃紧就会回收了,而改成500之后 第一次loop,没有回收等到调用gc执行完毕start-end逻辑后, 3 ,4,2,1,0都一个一个被回收了,从这里的消息也可以看出,回收虽然不会超大概率回收刚刚放进去的,但是也不会百分百先回收第一个,或者也许是日志打印和本地native消息不同步导致的??
看上去好像差不多,意思是在不定期检测 弱引用对象,那些不可达的进行清除.
但是没有说内存不足``oom```之前弱引用对象就一定已经被清除了。。
WeakHashMap 对于集合来说,用WeakHashMap也许更方便
软引用 手动调用System.gc回收的时候软引用不一定会回收, 但是弱引用一定会被回收,所以你是打算用软引用还是用弱引用呢?
为了加深印象避免混淆,我打算给他们取一个名字 ,软足 和 弱鸡g ,也就是软引用是内存不足才会瘦 ,弱引用 gc马上会瘦
参考链接
http://san-yun.iteye.com/blog/1683558
https://baijiahao.baidu.com/s?id=1578867464445861486&wfr=spider&for=pc
http://www.cnblogs.com/skywang12345/p/3154474.html
测试案例参考
http://wiseideal.iteye.com/blog/1469295

