Reputation:
My java application has memory leaks - when my resources clearing code is executing task manager shows that memory usage wasn't changed. My code
while (isRunning) {
try
{
selector.select();
long sum=0;
Set keys = selector.selectedKeys();
Iterator it = keys.iterator();
while(it.hasNext())
{
SelectionKey key = (SelectionKey)it.next();
if (key.isReadable())
{
SocketChannel sc = (SocketChannel) key.channel();
ByteBuffer bb;
if(key.attachment()==null)
{
bb = ByteBuffer.allocate(1024*1024);
key.attach(bb);
}
else
{
bb = (ByteBuffer)key.attachment();
bb.clear();
}
int x = sc.read(bb);
System.out.println(x +" bytes were read");
if(x==-1)
{
key.attach(null); //doesn't work
sc.close();
//bb = null; // also doesn't work
}
}
}
keys.clear();
}
catch (Exception ex)
{
ex.printStackTrace(new PrintStream(System.out));
}
finally
{
//stopServer();
}
}
Testing logic - I wrote simple TCP client java programm sending 100 messages to server. I intentionally allocated large buffer - 1MB for each connection. When client finishes his job int x = sc.read(bb);
returns -1 and the following code is executed:
if(x==-1)
{
key.attach(null); //doesn't work
sc.close();
//bb = null; // also doesn't work
}
I checked it with debug output, this code was really executed but task manager still showes large memory usage. where is the problem?
Upvotes: 0
Views: 568
Reputation: 311023
Certainly key.attach(null)
works. If it didn't, attaching a non-null object wouldn't work either. Same code.
But, in any case, closing the SocketChannel
cancels the key, which removes it from all key sets of all Selectors
it was registered with, so you will never see the key again anyway, so it becomes eligible for GC, and so does the attachment, regardless of whether you call key.attach(null)
or not, which is therefore redundant. Either you have another reference to your attachment somewhere else, or your memory usage problem is elsewhere.
Upvotes: 1