写了段测试代码,放在Activity的onCreate执行,代码如下: while (true) { String responseStr2 = "json数据"; Result<Map<String, Object>> responseObject = JSON.parseObject(responseStr2, new TypeReference<Result<Map<String, Object>>>() {}); } 在运行过程中可以看到内存一直在稳定增长,请问为什么没有释放掉? 如果循环里面没有使用TypeReference,内存稳定在一定区域。 我使用的是 compile 'com.alibaba:fastjson:1.1.58.android' 如果使用方式有问题,请帮我指出,谢谢!
[alibaba/fastjson]使用TypeReference导致我的应用内存泄露
回答
Result<Map<String, Object>> responseObject 你的这个引用每次指向的都是一个新对象,堆内存坑定爆炸
@jonenet 一次循环结束之后,这个对象不就没人引用他了吗,GC应该是可以回收掉的啊?实际回收不了。我不用TypeReference的时候,循环里面responseObject每次也是一个新的对象,但是这时候GC是可以回收的。
循环一段时间IdentityHashMap里面会越堆越多
我本地测试是正常的哦 jdk1.8.0_66.jdk
while (true) {
String responseStr2 = "{value:{'key':'value'}}";
Result<Map<String, Object>> responseObject = JSON.parseObject(responseStr2, new TypeReference<Result<Map<String, Object>>>() {});
}
public static class Result<T> {
public T value;
}
@wuwen5 测试用的是com.alibaba:fastjson:1.1.58.android 这个版本吗?
按照我的测试
TypeReference<Result<Map<String, Object>>> typeface = new TypeReference<Result<Map<String, Object>>>() {};
while (true) {
String responseStr2 = "{value:{'key':'value'}}";
Result<Map<String, Object>> responseObject = JSON.parseObject(responseStr2, typeface);
}
这样内存是稳定的,如果每次都在循环里面new一个TypeReference
protected TypeReference(){
Type superClass = getClass().getGenericSuperclass();
type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
}
debug看到这里获取的type每次都是一个新的实例,我看到说type会是IdentityHashMap的key对吧,这就可以解释为什么我这边map里的对象会越堆越多了。但是为什么你在循环里面每次也是new一个对象,测试会没问题,是我们用的fastjson版本不同吗 @wuwen5
针对我的情况,自己根据泛型缓存一份TypeReference private static Map<Class,TypeReference> resultMap; public static TypeReference<Result> getResultTypeReference(final K k){ if(resultMap == null){ resultMap = new HashMap<>(); } TypeReference<Result> typeReference = resultMap.get(k.getClass()); if(typeReference == null){ typeReference = new TypeReference<Result>(){}; resultMap.put(k.getClass(),typeReference); } return typeReference; } 能解决我现在遇到的问题,先不管了..如果有什么新的进展,please @我一下
@FJCDrome 我是在java jdk环境测试的, 奇怪 好像安卓的环境下确实有问题,我先装个安卓环境再试试.
另外你可以使用多参数的写法测试下,带参数的写法内部会自己缓存. 参考 https://github.com/alibaba/fastjson/wiki/TypeReference.
Result<Map<String, Object>> responseObject = JSON.parseObject(responseStr2, getType(String.class, Object.class));
<K, V> ParameterizedType getType(Class<K> k, Class<V> v) {
return (ParameterizedType)new TypeReference<Result<Map<K, V>>>(k, v) {}.getType();
}
@wuwen5 带参数的方式试了一下,直接拷例子的代码,没有内存泄露的问题。