7

I am using ObjectMapper from Jackson to convert the Java object to String in order to write it in my log file.
The converting method looks like:

private String getResponseAsString(OrderResponse response) {
        ObjectMapper mapper = new ObjectMapper();
        try {
            return mapper.writeValueAsString(response);
        } catch (JsonProcessingException e) {
            log.error("Error when converting response:" + getExceptionMessage(e));
            return "Error when converting response";
        }
}

After I ran my program, I saw that it threw the OutOfMemoryError: Java Heap Space error on this method:

Exception thrown so I think my program is running out of memory. I read some articles that I can overcome this problem by increasing the memory. But right now when I check the settings, the default Xmx in my computer is already nearly 4GB so I don't want to increase it more.

Can anyone give me a hint how can I save memory with this converting Object to String method by replacing it with another method that has the same function? Or does anyone have another idea/approach how to overcome this problem.

Allan
  • 12,117
  • 3
  • 27
  • 51
Bali
  • 705
  • 4
  • 13
  • 21
  • 7
    How big is the object you're serializing and what's its structure? – ernest_k Jun 28 '18 at 08:30
  • 1
    Do you have any recursive references? @JsonIgnore might help if an object refers to itself or you have objects that eventually refer back to the original object again. – Tschallacka Jun 28 '18 at 08:34
  • @Tschallacka wouldn't that give a `stackoverflow exception` instead?.. out of memory seems to be due to large complex structures. OP should try to split that and serialize it in parts. – Ovidiu Dolha Jun 28 '18 at 08:38
  • 1
    Well, if you have A -> B -> C -> D -> A and all refer back to each other and such it might go on for a while depending on complexity and then it's a case of who comes first, the stack overflow or the out of memory. I've had out of memories in similar serializations with too complex objects. – Tschallacka Jun 28 '18 at 08:41
  • Hi @ErnestKiwele: my object has around 25 properties with different types, ex String, Integer, Array, another object insides... and for the whole application I have around 20 objects like this – Bali Jun 28 '18 at 08:41
  • Hi @Tschallacka: yes in my object i have reference to another object and do you think it might be the cause? – Bali Jun 28 '18 at 08:42
  • possibly. You should sketch out your object yourself with pen and paper, it comes clear quickly that way what references what and what loads what. That way you document for yourself what is all loaded in this object, and by tracing it that way you soon enough notice if there's a back reference or a huge trail loaded somewhere with unexpected objects. – Tschallacka Jun 28 '18 at 08:46
  • thank you @Tschallacka, i will try it. And might I ask another question that is it safe that I create a static objectmapper and use only this object for the whole application, so I do not need to create the object everytime I call the method. Is it saving the memory also? – Bali Jun 28 '18 at 08:56
  • @Bali yes, ObjectMapper is threadsafe and thus safe (and suggested) to use a single instance per application – Felix Mar 04 '21 at 11:59

2 Answers2

2

I faced exactly the same issue, you are trying to convert a really large object into a string. In Java, the String object has a limitation on the length it can have and hence the memory it can store. Refer to this answer.
In my scenario, I was able to resolve the issue by instead using
new ObjectMapper().writeValueAsBytes(response)
According to my understanding, increasing the heap space won't help and it indeed didn't work for me.

Dexter Legaspi
  • 3,192
  • 1
  • 35
  • 26
1

You have a heavy java object, you need write a java object into the file. and follow the link Click Here

 private File getResponseAsString(OrderResponse response) throws JsonGenerationException, JsonMappingException, IOException {
    ObjectMapper mapper = new ObjectMapper();
    File file = new File("D:/cp/dataOne.json");
    mapper.writeValue(file, response);
    return file;
}
Faiz Akram
  • 559
  • 4
  • 10