[ https://issues.apache.org/jira/browse/JOHNZON-396?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Romain Manni-Bucau updated JOHNZON-396: --------------------------------------- Fix Version/s: 2.0.1 (was: 2.1.0) > JsonStreamParserImpl has a memory leak problem > ---------------------------------------------- > > Key: JOHNZON-396 > URL: https://issues.apache.org/jira/browse/JOHNZON-396 > Project: Johnzon > Issue Type: Bug > Components: Core > Affects Versions: 1.1.13, 1.2.19 > Reporter: liucongcong > Assignee: Markus Jung > Priority: Major > Fix For: 1.2.22, 2.0.1 > > Attachments: image-2023-04-09-12-44-02-385.png, > image-2023-04-09-12-44-39-048.png, image-2023-04-09-12-45-10-166.png > > > When some large strings are parsed, the JsonStreamParserImpl's buffer will > doAutoAdjust(..). > In doAutoAdjust method, the first time fallBackCopyBuffer will release to > bufferProvider, i found the fallBackCopyBuffer is from valueBuffer but > release to bufferProvider. > When using the default QUEUE BufferStrategy and always trigger the > doAutoAdjust will cause a OOM fault. > > this is my unit test case: > > {code:java} > import java.io.StringReader; > import java.util.HashMap; > import java.util.Map; > import javax.json.spi.JsonProvider; > import javax.json.stream.JsonParser; > import javax.json.stream.JsonParserFactory; > import org.apache.johnzon.core.JsonParserFactoryImpl; > import org.junit.Test; > public class JsonStreamBufferMemoryLeakTestCase { > @Test > public void normalCase() { > Map<String, Object> config = new HashMap<>(); > config.put(JsonParserFactoryImpl.MAX_STRING_LENGTH, 4); > JsonParserFactory parserFactory = JsonProvider.provider() > .createParserFactory(config); > JsonParser parser = parserFactory > .createParser(new StringReader("{ \"a\": \"\\\"a2\\\"\" }")); > parser.getValue(); > parser.close(); > // parserFactory.bufferProvider.queue.size() = 1 > // parserFactory.valueBufferProvider.queue.size() = 1 > System.out.println(parserFactory); // debugger breakpoint for view queue > size. > } > @Test > public void leakCase() { > Map<String, Object> config = new HashMap<>(); > config.put(JsonParserFactoryImpl.MAX_STRING_LENGTH, 2); > JsonParserFactory parserFactory = JsonProvider.provider() > .createParserFactory(config); > JsonParser parser = parserFactory > .createParser(new StringReader("{ \"a\": \"\\\"a2\\\"\" }")); > parser.getValue(); > parser.close(); > // expect: parserFactory.bufferProvider.queue.size() = 1 and > parserFactory.valueBufferProvider.queue.size() = 1 > // but: parserFactory.bufferProvider.queue.size() = 2 and > parserFactory.valueBufferProvider.queue.size() = 0 > parser = parserFactory > .createParser(new StringReader("{ \"a\": \"\\\"a2\\\"\" }")); > parser.getValue(); > parser.close(); > // expect: parserFactory.bufferProvider.queue.size() = 1 and > parserFactory.valueBufferProvider.queue.size() = 1 > // but: parserFactory.bufferProvider.queue.size() = 3 and > parserFactory.valueBufferProvider.queue.size() = 0 > parser = parserFactory > .createParser(new StringReader("{ \"a\": \"\\\"a2\\\"\" }")); > parser.getValue(); > parser.close(); > // expect: parserFactory.bufferProvider.queue.size() = 1 and > parserFactory.valueBufferProvider.queue.size() = 1 > // but: parserFactory.bufferProvider.queue.size() = 4 and > parserFactory.valueBufferProvider.queue.size() = 0 > System.out.println(parserFactory); // debugger breakpoint for view queue > size. > } > }{code} > source code analysis: > !image-2023-04-09-12-44-02-385.png|width=734,height=185! > > !image-2023-04-09-12-44-39-048.png|width=716,height=203! > !image-2023-04-09-12-45-10-166.png|width=702,height=122! > > > > -- This message was sent by Atlassian Jira (v8.20.10#820010)