Skip to content

Commit f905f48

Browse files
Elin-ZhoueLin
authored andcommitted
fix: cache ObjectWriter created in switch block of getObjectWriterInternal to prevent Metaspace leak, for issue #7626
1 parent 3697c2d commit f905f48

2 files changed

Lines changed: 124 additions & 0 deletions

File tree

core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterProvider.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,16 @@ private ObjectWriter getObjectWriterInternal(Type objectType, Class objectClass,
708708
break;
709709
}
710710

711+
if (objectWriter != null) {
712+
ObjectWriter previous = fieldBased
713+
? cacheFieldBased.putIfAbsent(objectType, objectWriter)
714+
: cache.putIfAbsent(objectType, objectWriter);
715+
if (previous != null) {
716+
objectWriter = previous;
717+
}
718+
return objectWriter;
719+
}
720+
711721
if (objectWriter == null
712722
&& (!fieldBased)
713723
&& Map.class.isAssignableFrom(objectClass)
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package com.alibaba.fastjson2.writer;
2+
3+
import com.alibaba.fastjson2.JSON;
4+
import com.google.common.collect.ArrayListMultimap;
5+
import com.google.common.collect.HashMultimap;
6+
import com.google.common.collect.LinkedHashMultimap;
7+
import com.google.common.collect.LinkedListMultimap;
8+
import com.google.common.collect.TreeMultimap;
9+
import org.junit.jupiter.api.Tag;
10+
import org.junit.jupiter.api.Test;
11+
12+
import static org.junit.jupiter.api.Assertions.assertEquals;
13+
import static org.junit.jupiter.api.Assertions.assertNotNull;
14+
import static org.junit.jupiter.api.Assertions.assertSame;
15+
16+
@Tag("writer")
17+
public class GuavaMultimapWriterCacheTest {
18+
@Test
19+
public void testLinkedListMultimapWriterCached() {
20+
ObjectWriterProvider provider = new ObjectWriterProvider();
21+
ObjectWriter w1 = provider.getObjectWriter(LinkedListMultimap.class);
22+
ObjectWriter w2 = provider.getObjectWriter(LinkedListMultimap.class);
23+
assertNotNull(w1);
24+
assertSame(w1, w2);
25+
}
26+
27+
@Test
28+
public void testArrayListMultimapWriterCached() {
29+
ObjectWriterProvider provider = new ObjectWriterProvider();
30+
ObjectWriter w1 = provider.getObjectWriter(ArrayListMultimap.class);
31+
ObjectWriter w2 = provider.getObjectWriter(ArrayListMultimap.class);
32+
assertNotNull(w1);
33+
assertSame(w1, w2);
34+
}
35+
36+
@Test
37+
public void testHashMultimapWriterCached() {
38+
ObjectWriterProvider provider = new ObjectWriterProvider();
39+
ObjectWriter w1 = provider.getObjectWriter(HashMultimap.class);
40+
ObjectWriter w2 = provider.getObjectWriter(HashMultimap.class);
41+
assertNotNull(w1);
42+
assertSame(w1, w2);
43+
}
44+
45+
@Test
46+
public void testLinkedHashMultimapWriterCached() {
47+
ObjectWriterProvider provider = new ObjectWriterProvider();
48+
ObjectWriter w1 = provider.getObjectWriter(LinkedHashMultimap.class);
49+
ObjectWriter w2 = provider.getObjectWriter(LinkedHashMultimap.class);
50+
assertNotNull(w1);
51+
assertSame(w1, w2);
52+
}
53+
54+
@Test
55+
public void testTreeMultimapWriterCached() {
56+
ObjectWriterProvider provider = new ObjectWriterProvider();
57+
ObjectWriter w1 = provider.getObjectWriter(TreeMultimap.class);
58+
ObjectWriter w2 = provider.getObjectWriter(TreeMultimap.class);
59+
assertNotNull(w1);
60+
assertSame(w1, w2);
61+
}
62+
63+
@Test
64+
public void testLinkedListMultimapSerialize() {
65+
LinkedListMultimap<String, String> map = LinkedListMultimap.create();
66+
map.put("a", "1");
67+
map.put("a", "2");
68+
map.put("b", "3");
69+
String json = JSON.toJSONString(map);
70+
assertEquals("{\"a\":[\"1\",\"2\"],\"b\":[\"3\"]}", json);
71+
72+
String json2 = JSON.toJSONString(map);
73+
assertEquals(json, json2);
74+
}
75+
76+
@Test
77+
public void testArrayListMultimapSerialize() {
78+
ArrayListMultimap<String, Integer> map = ArrayListMultimap.create();
79+
map.put("k1", 1);
80+
map.put("k1", 2);
81+
String json = JSON.toJSONString(map);
82+
assertEquals("{\"k1\":[1,2]}", json);
83+
84+
String json2 = JSON.toJSONString(map);
85+
assertEquals(json, json2);
86+
}
87+
88+
@Test
89+
public void testHashMultimapSerialize() {
90+
HashMultimap<String, String> map = HashMultimap.create();
91+
map.put("k", "v");
92+
String json = JSON.toJSONString(map);
93+
assertEquals("{\"k\":[\"v\"]}", json);
94+
}
95+
96+
@Test
97+
public void testLinkedHashMultimapSerialize() {
98+
LinkedHashMultimap<String, String> map = LinkedHashMultimap.create();
99+
map.put("a", "1");
100+
map.put("a", "2");
101+
map.put("b", "3");
102+
String json = JSON.toJSONString(map);
103+
assertEquals("{\"a\":[\"1\",\"2\"],\"b\":[\"3\"]}", json);
104+
}
105+
106+
@Test
107+
public void testTreeMultimapSerialize() {
108+
TreeMultimap<String, String> map = TreeMultimap.create();
109+
map.put("b", "2");
110+
map.put("a", "1");
111+
String json = JSON.toJSONString(map);
112+
assertEquals("{\"a\":[\"1\"],\"b\":[\"2\"]}", json);
113+
}
114+
}

0 commit comments

Comments
 (0)