[liblouis-liblouisxml] Re: Potential memory leak around using table resolvers

  • From: "Michael Whapples" <dmarc-noreply@xxxxxxxxxxxxx> (Redacted sender "mwhapples" for DMARC)
  • To: liblouis-liblouisxml@xxxxxxxxxxxxx
  • Date: Wed, 3 Aug 2016 11:36:40 +0100

Reading more into the JavaDocs for JNA I still feel may be the StringArray approach is more correct, but I do get a few questions I will ask the JNA developers.


StringArray extends Memory, which has for the class description:

"A Pointer to memory obtained from the native heap via a call to malloc.
In some cases it might be necessary to use memory obtained from malloc. For example, Memory helps accomplish the following idiom:
                void *buf = malloc(BUF_LEN * sizeof(char));
                call_some_function(buf);
                free(buf);

The finalize() method will free allocated memory when this object is no longer referenced."

That last sentence is mainly what concerns me, if LibLouis were to free that memory will it cause an issue?


Also I think that also means that LibLouis would probably want to copy the string array and then free the original it got back.


May be an alternative is to write our own specific class extending Pointer and we can deal with these concerns. However may be wait until I hear back from the JNA developers.


Michael Whapples


On 02/08/2016 18:25, Bert Frees wrote:

Hi Michael,

You are absolutely correct about the memory leak, and also about the reason why it was done.

When I added this code I was fully aware I was adding a leak, but judged it was negligible because it's not a critical function at all. It'll be called only as many times as the number of distinct tables that you load.

I wasn't aware of the StringArray solution. I'll have a look and see whether I can use it.

Thanks!

2016-08-02 17:29 GMT+02:00 Michael Whapples <dmarc-noreply@xxxxxxxxxxxxx <mailto:dmarc-noreply@xxxxxxxxxxxxx>>:

    I think I have identified a potential memory leak around the use
    of a table resolver in LibLouis.


    The function resolveTable looks like:

    char** resolveTable(const char *tableList, const char *base)

    {

      return copyStringArray((*tableResolver)(tableList, base));

    }


    I think I may understand why this was done. In liblouis-java I
    notice that the resolver there returns String[] and according to
    the JNA documents this will only last whilst the String[] object
    is not garbage collected (IE. reliably only whilst a reference is
    held) and as the method is just returning it then no reference is
    being held so you are copying it before garbage collection frees it.


    Why I think this is a memory leak. If a resolver was to do things
    in the more normal way of expecting the caller who recieves the
    returned value to free the memory, then the returned array will
    never be freed.


    I am not a C expert so may be I miss something, but I am uncertain
    how a C application with a custom table resolver would get that
    memory of the returned array freed.


    If changing it so that LibLouis does free the memory of the
    returned array, you may have the question of how liblouis-java
    should overcome the issue of garbage collection freeing the memory
    as well. The answer I think is to use JNA's StringArray class.
    StringArray creates a string array in native memory and is easy to
    create from a Java String[] object, there is the constructor
    StringArray(String[]).


    So is my thought of there being a memory leak correct,
    particularly when thinking about languages like C without garbage
    collection?


    Do I need to explain more about JNA;s StringArray class and how
    liblouis-java could be fixed?


    Michael Whapples

    For a description of the software, to download it and links to
    project pages go to http://liblouis.org



Other related posts: