fastjson中JSON.toJSONString記憶體洩露如何解決

2020-10-19 11:00:58

記憶體洩露

將資料寫入到了Tomcat執行緒池管理的執行緒中

產生原因

public static String toJSONString(Object object, // 
                                      SerializeConfig config, // 
                                      SerializeFilter[] filters, // 
                                      String dateFormat, //
                                      int defaultFeatures, // 
                                      SerializerFeature... features) {
        SerializeWriter out = new SerializeWriter(null, defaultFeatures, features);

        try {
            JSONSerializer serializer = new JSONSerializer(out, config);
            
            if (dateFormat != null && dateFormat.length() != 0) {
                serializer.setDateFormat(dateFormat);
                serializer.config(SerializerFeature.WriteDateUseDateFormat, true);
            }

            if (filters != null) {
                for (SerializeFilter filter : filters) {
                    serializer.addFilter(filter);
                }
            }

            serializer.write(object);

            return out.toString();
        } finally {
            //洩露的地方
            //將buf中的json字串放入到threadLocal
            out.close();
        }
    }

進入這個方法,仔細看一下

public void close() {
        if (writer != null && count > 0) {
            flush();
        }
        //解決方案就從這個地方下手
        if (buf.length <= BUFFER_THRESHOLD) {
            bufLocal.set(buf);
        }

        this.buf = null;
    }

解決方案

A

不再使用fastjson

B

調整BUFFER_THRESHOLD引數

如何調整

public static void main(String[] args) {
        //在啟動類上加入該引數,進行修改
        System.setProperty("fastjson.serializer_buffer_threshold","64");
        SpringApplication.run(SpringbootDemoApplication.class, args);


    }

為什麼這樣調整會起作用

這個值不可以設定的小於64,也不可以大於1024*64,否則都不會起作用

 而我們的目的是控制BUFFER_THRESHOLD,進行影響buf,為的就是不讓buf寫入threadLocal,或者儘可能少的寫入threadLocal