8

Am using Jackson mapper to convert my java objects to String, But these objects are not removed by GC in heap.

My code

List<Object[]> reportList; // This contains my objects

ObjectMapper map = new ObjectMapper(); // org.codehaus.jackson.map.ObjectMapper

return map.writeValueAsString(reportList);

This returns String to my view layer, But Objects parsed via object mapper retained in heap. I have taken heap dump.

Class Name              |  Objects | Shallow Heap | Retained Heap
------------------------------------------------------------------
char[]                  | 5,03,267 |  5,48,74,336 | >= 54,874,336
byte[]                  |   18,067 |  3,09,01,016 | >= 30,901,016
java.lang.reflect.Method| 2,60,262 |  2,08,20,960 | >= 32,789,040
java.util.HashMap$Entry | 4,31,423 |  1,38,05,536 | >= 92,963,752
java.lang.String        | 4,97,172 |  1,19,32,128 | >= 60,889,416
------------------------------------------------------------------

While seeing char

Class Name                                                            | Shallow Heap | Retained Heap
-----------------------------------------------------------------------------------------------------
[2] char[4][] @ 0x72119e690                                           |           32 |      5,28,352
'- _charBuffers org.codehaus.jackson.util.BufferRecycler @ 0x72119e658|           24 |      5,28,408
-----------------------------------------------------------------------------------------------------
Class Name                                                            | Shallow Heap | Retained Heap
-----------------------------------------------------------------------------------------------------
[2] char[4][] @ 0x721158a78                                           |           32 |      5,28,352
'- _charBuffers org.codehaus.jackson.util.BufferRecycler @ 0x721158a40|           24 |      5,28,408
-----------------------------------------------------------------------------------------------------
Class Name                                                            | Shallow Heap | Retained Heap
-----------------------------------------------------------------------------------------------------
[2] char[4][] @ 0x7210bc5e0                                           |           32 |      5,28,352
'- _charBuffers org.codehaus.jackson.util.BufferRecycler @ 0x7210bc5a8|           24 |      5,28,408
-----------------------------------------------------------------------------------------------------

How to clean these objects from heap, is there any cleanup method exist.

Akalya
  • 876
  • 8
  • 12
  • I am using JProfiller to monitor and investigate memory issues and I did a simple test: I've generated two huge JSON files 250MB each and then converts it into the Java objects using ObjectMapper. Total memory usage was more than 500MB but it went down to 3.8kB after I initiated GC. Did you initiated GC or you just waited for some time? Was GC initiated? – Ilya Ovesnov Dec 19 '14 at 19:00
  • @llya i haven't initiate GC manually.Do i need to call System.gc() in my finally block to clear these objects? – Akalya Dec 22 '14 at 06:00
  • Yes, try to call System.gc(). At least I didn't see any memory leaks and that all memory got released after I initiated GC. – Ilya Ovesnov Dec 22 '14 at 09:03
  • But most of them suggesting me to not use System.gc() manually(http://stackoverflow.com/questions/2414105/why-is-it-bad-practice-to-call-system-gc), is there any other solution for this issue? Please help me – Akalya Dec 22 '14 at 11:38
  • You created a question where you asking about memory leaks in Jackson. You cannot say that you found memory leak and the memory dump doesn't show anything if GC was not triggered. I would agree that you should not run it in runtime in your code but you wanted to verify is there a memory leak or not. If you run System.gc() and memory will be released then you can remove that line of code and be sure that all these objects will be released when GC will be triggered. – Ilya Ovesnov Dec 22 '14 at 16:34
  • Thank you so much, let me check the same – Akalya Dec 23 '14 at 04:58

1 Answers1

2

Memory usage you observe is due to buffer recycling that uses per-thread SoftReference to hold on to couple of parsing buffers (a byte[] one, another char[]) one. These will be reclaimed if there is memory pressure; but as long as there is plenty of heap, they are retained and reused. This can be significant performance improvement, as such buffers need not be allocated, cleared, and GC'ed.

So it should not be a problem -- this is similar to disk caching that OS does, using memory blocks for disk cache when there is memory to spare.

StaxMan
  • 113,358
  • 34
  • 211
  • 239