High memory consumption by duplicate strings when returning thousands of rows
MyBatis version
3.1.1 - latest (3.5.10)
Database vendor and version
PostgreSQL v12
Test case or example project
https://github.com/MatIvan/batis-leaks-demo
Steps to reproduce
Described in attached PDF MyBatis-v3-memory-consumption.pdf
Hello @alcobass ,
Thank you for the detailed report.
I just took a quick look, but specifying <id /> may help.
Here is an excerpt from the doc.
Very Important: id elements play a very important role in Nested Result mapping. You should always specify one or more properties that can be used to uniquely identify the results. The truth is that MyBatis will still work if you leave it out, but at a severe performance cost. Choose as few properties as possible that can uniquely identify the result. The primary key is an obvious choice (even if composite).
Hello @alcobass ,
Thank you for the detailed report.
I just took a quick look, but specifying
<id />may help. Here is an excerpt from the doc.Very Important: id elements play a very important role in Nested Result mapping. You should always specify one or more properties that can be used to uniquely identify the results. The truth is that MyBatis will still work if you leave it out, but at a severe performance cost. Choose as few properties as possible that can uniquely identify the result. The primary key is an obvious choice (even if composite).
Hi.
Added field “id” to table and mapper and then repeated test. Memory leak decrease at 64%, but problem not solved. MyBatis leaves a lot of rubbish in memory after requests

The mapper file for the leak demo is still incorrect. The column mapping for the ID property of the inner object is mapped to "ID" and it should be mapped to "inner_ID".
This may not fix the problem but see if it helps some more.
The mapper file for the leak demo is still incorrect. The column mapping for the ID property of the inner object is mapped to "ID" and it should be mapped to "inner_ID".
This may not fix the problem but see if it helps some more.
"inner_" prefix is added via "columnPrefix" param in association
<association property="innerTestBean" columnPrefix="inner_" resultMap="InnerTestBeanMap"></association>
Thank you for the demo and explanation, @alcobass .
If the used memory is garbage collected, it's technically not a memory leak. MyBatis creates many String instances indeed, but they are necessary to process complex mapping. I'm not exactly sure what you are proposing, but if you have a nice optimization idea, please send us a PR and we will review it.
I'm going to close this as it works as expected.