0

LibUSB (USB4Java) requires use of Direct ByteBuffers for sending/receiving bulk transfers.

The problem is that according to the documentation for java.nio.ByteBuffer Direct ByteBuffer is out of Java HEAP and therefore it is out of reach of GarbageCollector.

I have implemented a message sender/receiver in java with use of LibUSB bulk sending, but it is rapidly draining all of my RAM.

private synchronized boolean send(String msg) {
    //...
    bytes = msg.getBytes("UTF-8");
    sendBuff = ByteBuffer.allocateDirect(bytes.length);
    sendBuff.put(bytes);
    intBuffer = IntBuffer.allocate(1);
    result = LibUsb.bulkTransfer(handle, (byte) 0x02, sendBuf, intBuffer, 0);
    try {
        if (result < 0) throw new LibUsbException(result);
    } catch (LibUsbException e) {
        e.printStackTrace();
    }
    return true;
} 

// This is in separate thread
public void run() {
    try {
        IntBuffer transfered = IntBuffer.allocate(1);
        int result;
        ByteBuffer recBuffer = ByteBuffer.allocateDirec(500000);
        while ((result = LibUsb.bulkTransfer(handle, (byte) 0x81, recBuffer, transfered, 0)) >= 0) {
            final int transferLength = transfered.get();
            final byte[] bytes = new byte[transferLength];
            recBuffer.get(bytes);

            //....
       }
       throw new LibUsbException(result);
   } finally {
       logWriter.info("Receiver thread finished.");
       client.connected = false;
   }
}

I've figured out that I can reuse the recBuffer and use clear() to reset it before every call, however the sendBuff is variable length so I cannot reuse that one.

If i leave this running for more than 20min all of my RAM is depleted. Sometimes it will result in outofmemory exception, however most of the time it will just exit or the thread will be lost.

Any ideas on how to property use ByteBuffers in this?

trincot
  • 317,000
  • 35
  • 244
  • 286
Mazmart
  • 2,703
  • 4
  • 17
  • 20
  • I don't see why you can't reuse the send buffer. Just allocate it to the largest message size you're going to send, or implement a grow-as-needed technique. What matters when sending is the limit, not the capacity. – user207421 Oct 26 '16 at 22:39
  • For deallocating Direct Buffers see http://stackoverflow.com/questions/1854398/how-to-garbage-collect-a-direct-buffer-java and http://stackoverflow.com/questions/3496508/deallocating-direct-buffer-native-memory-in-java-for-jogl/26777380#26777380 – dryman Oct 27 '16 at 08:00

0 Answers0