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