[
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)