https://www.jianshu.com/p/876d443c2162
at java.lang.OutOfMemoryError.<init>()V (OutOfMemoryError.java:48)
at com.alibaba.fastjson.serializer.SerializeWriter.expandCapacity(I)V (SerializeWriter.java:249)
-rw------- 1 xx xx 2043416350 Nov 24 11:37 java_pid8068.hprof
-rw------- 1 xx xx 2028797313 Nov 24 11:17 java_pid4671.hprof
-rw------- 1 xx xx 1477222612 Nov 23 23:25 java_pid31563.hprof
num #instances #bytes class name
----------------------------------------------
1: 146219 741203672 [Ljava.lang.Object;
2: 2842356 639498168 [C
HeroPersonality hp = new HeroPersonality();
hp.setPersonalityLevel(1);
String str = JSON.toJSONString(hp);
在我写本地测试代码重现的时候 我写了一个反序列化HeroPersonality的例子
先用HeroPersonality序列化为一堆字符串,然后尝试在这堆字符串加入一些额外信息,然后再反序列化
不经意的发现
伪测试代码
PersonalityStrengthenConfig config = DataConfigService.
getSettingById(PersonalityStrengthenConfig.class, 1);
System.out.println("dcs.config1:" + config.cost);
System.out.println("dcs.config1:" + config.attr_num);
for (int i = 0; i < 10; i++) {
String str1 = "{...}";
JSON.parseObject(str1, HeroPersonality.class);
}
System.out.println("dcs.config2:" + config.cost);
System.out.println("dcs.config2:" + config.attr_num);
结果输出
这个结果让我惊喜,让我非常的肯定,cost中的大量null就是这样产生的,而且我最早就怀疑HeroPersonality中有一些非序列化的get方法有一些问题;而同样的attr_num也是JSONArray类型,就没有任何问题.问题初步锁定在HeroPersonality中的一个get方法.
public JSONArray getNextTrainCost() {
return ((PersonalityStrengthenConfig) getConfig()).cost;
}
@Override
public DataConfigItem getConfig() {
return DataConfigService.getSettingById(PersonalityStrengthenConfig.class,
personalityLevel);
}
// FieldDeserializer#setValue 其中method就是getNextTrainCost() 即获取方法的返回值然后加了一个null
Collection collection = (Collection) method.invoke(object);
if (collection != null) {
collection.addAll((Collection) value);
}