Skip to content

Commit

Permalink
fix ParameterizedTypeImpl memory leak case, fix #3329
Browse files Browse the repository at this point in the history
  • Loading branch information
wenshao committed Jul 19, 2020
1 parent 545a06b commit 38070ca
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/main/java/com/alibaba/fastjson/TypeReference.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,16 @@ protected TypeReference(Type... actualTypeArguments){
}

type = cachedType;
}

public static Type intern(ParameterizedTypeImpl type) {
Type cachedType = classTypeCache.get(type);
if (cachedType == null) {
classTypeCache.putIfAbsent(type, type);
cachedType = classTypeCache.get(type);
}

return cachedType;
}

private Type handlerParameterizedType(ParameterizedType type, Type[] actualTypeArguments, int actualIndex) {
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/com/alibaba/fastjson/parser/ParserConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ public static ParserConfig getGlobalInstance() {
0xA123A62F93178B20L,
0xA85882CE1044C450L,
0xAA3DAFFDB10C4937L,
0xAAAA0826487A3737L,
0xAC6262F52C98AA39L,
0xAD937A449831E8A0L,
0xAE50DA1FAD60A096L,
Expand Down Expand Up @@ -615,6 +616,11 @@ public ObjectDeserializer getDeserializer(Type type) {

public ObjectDeserializer getDeserializer(Class<?> clazz, Type type) {
ObjectDeserializer deserializer = get(type);
if (deserializer == null && type instanceof ParameterizedTypeImpl) {
Type innerType = TypeReference.intern((ParameterizedTypeImpl) type);
deserializer = get(innerType);
}

if (deserializer != null) {
return deserializer;
}
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/com/alibaba/fastjson/util/IdentityHashMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,15 @@ public Entry(K key, V value, int hash, Entry<K, V> next){
public void clear() {
Arrays.fill(this.buckets, null);
}

public int size() {
int count = 0;
for (Entry<K, V> bucket : this.buckets) {
for (; bucket != null; bucket = bucket.next) {
count++;
}
}

return count;
}
}
38 changes: 38 additions & 0 deletions src/test/java/com/alibaba/json/bvt/issue_3300/Issue3329.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.alibaba.json.bvt.issue_3300;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
import com.alibaba.fastjson.util.IdentityHashMap;
import com.alibaba.fastjson.util.ParameterizedTypeImpl;
import junit.framework.TestCase;
import java.util.List;

import java.lang.reflect.Type;

public class Issue3329 extends TestCase {
public void test_for_issue() throws Exception {
ParserConfig config = new ParserConfig();
IdentityHashMap<Type, ObjectDeserializer> deserializers = config.getDeserializers();
int initSize = deserializers.size();
for (int i = 0; i < 1000 * 10; ++i) {
assertEquals(123,
((VO<User>) JSON.parseObject("{\"value\":{\"id\":123}}",
new ParameterizedTypeImpl(new Type[] {User.class}, null, VO.class),
config
)).value.id
);
}


assertEquals(2, deserializers.size() - initSize);
}

public static class VO<T> {
public T value;
}

public static class User {
public int id;
}
}

0 comments on commit 38070ca

Please sign in to comment.