COM getStringProperty() memory leak

36 views
Skip to first unread message

sdorof

unread,
Oct 26, 2017, 7:23:08 PM10/26/17
to Java Native Access
I have some COM-server from which I want to get a string property. For this I use COMLateBindingObject#getStringProperty(). It is works, but I have a memory leak.  There is nothing specials, I invoke only getStringProperty(). If I not use this function (just replacing the value by a constant string for the purposes of my program), the leaks disapear. So, is there a bug in JNA? And is there an alternative way to get string property from COM? Is there a some way to free the COM returnted string if the bug on the server side?

Best regards, 
S.D.

L Will Ahonen

unread,
Oct 27, 2017, 12:55:53 PM10/27/17
to Java Native Access
Hi,

How do you know you have a memory leak, and that it's caused by that exact function?

BR,
Will

sdorof

unread,
Oct 27, 2017, 1:20:14 PM10/27/17
to Java Native Access
HI

In my application I have a method to get a string from COM-server, like this:

class MyComProxy extends COMLateBindingObject {
 
...
 
public String getData() {
   
return getStringProperty("my_property");
 
}
}



When the application run, the Task Manager shows endless growth in memory until  the COMException "There was not enough memory to complete the operation" followed by OutOfMemory exception. This occurs about 2GB used memory as showed in the Task Manager. In the same time the java's MissionControl shows the used Heap memory less 256MB. 

Next, I change my code to like this:

class MyComProxy extends COMLateBindingObject {
 
...
 
public String getData() {
   
//return getStringProperty("my_property");
   
String data = createRandomDataString();
   
return data;
 
}
}

In this variant the memory stops growth.
So, I think the problem is in the getStringProperty() function.



пятница, 27 октября 2017 г., 19:55:53 UTC+3 пользователь L Will Ahonen написал:

Timothy Wall

unread,
Oct 27, 2017, 2:02:30 PM10/27/17
to jna-...@googlegroups.com
What you need to do is change the function signature to return a Pointer, create a String using Pointer.getString(0), and then free the pointer before returning.

--
You received this message because you are subscribed to the Google Groups "Java Native Access" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jna-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Matthias Bläsing

unread,
Oct 27, 2017, 2:14:24 PM10/27/17
to jna-...@googlegroups.com
Hey,

Am Freitag, den 27.10.2017, 14:02 -0400 schrieb Timothy Wall:
What you need to do is change the function signature to return a Pointer, create a String using Pointer.getString(0), and then free the pointer before returning.

I disagree. The problem is most probably the handling of Variant in COMLateBindingObject#getStringProperty. Variants that hold strings utilize a BSTR. BSTRs are special in the sense, that they are allocated by SysAllocString and freed by SysFreeString.

For Variants this is handled by VariantClear. VariantClear clears the data contained in the Variant and frees that data (not the Variant itself!).

On Fri, Oct 27, 2017 at 1:20 PM, sdorof <sdo...@gmail.com> wrote:
HI

In my application I have a method to get a string from COM-server, like this:

class MyComProxy extends COMLateBindingObject {
  ...
  public String getData() {
    return getStringProperty("my_property");
  }
}



When the application run, the Task Manager shows endless growth in memory until  the COMException "There was not enough memory to complete the operation" followed by OutOfMemory exception. This occurs about 2GB used memory as showed in the Task Manager. In the same time the java's MissionControl shows the used Heap memory less 256MB. 


Yes this is the implementation of getStringProperty:

    protected String getStringProperty(String propertyName) {
        VARIANT.ByReference result = new VARIANT.ByReference();
        this.oleMethod(OleAuto.DISPATCH_PROPERTYGET, result,
                this.getIDispatch(), propertyName);
        
        return result.stringValue();
    }

So there is no VariantClear call. This would be ok for "basic" variants, that only hold basic values (in this case the value is stored in the autoallocated structure mememory), but not for "complex" types like strings.

@sdorof can you build jna-platform from source and modify the implementation to:

    protected String getStringProperty(String propertyName) {
        VARIANT.ByReference result = new VARIANT.ByReference();
        this.oleMethod(OleAuto.DISPATCH_PROPERTYGET, result,
                this.getIDispatch(), propertyName);
        
        String res = result.stringValue();
        
        OleAuto.INSTANCE.VariantClear(result);
        
        return res;
    }

Thank you

Matthias

Сергей Дорофеенко

unread,
Oct 28, 2017, 3:41:07 PM10/28/17
to jna-...@googlegroups.com
Hi

пт, 27 окт. 2017, 21:14 Matthias Bläsing <mbla...@doppel-helix.eu>:

Yes, this solve the problem. Thanks.

Sergei D.


Thank you

Matthias

--
You received this message because you are subscribed to a topic in the Google Groups "Java Native Access" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/jna-users/jgI3YVbKpRU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to jna-users+...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages