[alibaba/fastjson]使用TypeReference导致我的应用内存泄露

2025-11-24 908 views
9

写了段测试代码,放在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' 如果使用方式有问题,请帮我指出,谢谢!

回答

5

Result<Map<String, Object>> responseObject 你的这个引用每次指向的都是一个新对象,堆内存坑定爆炸

0

@jonenet 一次循环结束之后,这个对象不就没人引用他了吗,GC应该是可以回收掉的啊?实际回收不了。我不用TypeReference的时候,循环里面responseObject每次也是一个新的对象,但是这时候GC是可以回收的。

6

2

循环一段时间IdentityHashMap里面会越堆越多

7

我本地测试是正常的哦 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;
    }
4

@wuwen5 测试用的是com.alibaba:fastjson:1.1.58.android 这个版本吗?

9

0

按照我的测试

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

6

针对我的情况,自己根据泛型缓存一份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 @我一下

8

@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();
    }
0

@wuwen5 带参数的方式试了一下,直接拷例子的代码,没有内存泄露的问题。