isaac.hazan
isaac.hazan

Reputation: 3874

Linux File descriptors

I have a Java program after 2 weeks of running in average will become stuck and produce the following error:

Caused by: java.net.SocketException: Too many open files
        at sun.nio.ch.Net.socket0(Native Method)
        at sun.nio.ch.Net.socket(Net.java:415)
        at sun.nio.ch.Net.socket(Net.java:408)
        at sun.nio.ch.SocketChannelImpl.<init>(SocketChannelImpl.java:105)

That hints to me that many sockets are opened but never closed. Before diving into programmatic instrumentation i started to inspect what information i could draw from linux itself. I am using Redhat.

And then, a few questions came up as follows:

  1. Why the following commands do not give the same output?

See

[ec2-user@ip-172-22-28-102 ~]$ sudo ls /proc/32085/fd | wc -l
592
[ec2-user@ip-172-22-28-102 ~]$ sudo lsof -a -p 32085 | wc -l 
655
  1. Is there a way to know from the proc stat info which thread created which file descriptor?

It seems like there is not because if i do the following, i am getting the same information:

[ec2-user@ip-172-22-28-102 ~]$ sudo ls /proc/32085/task/22386/fd | wc -l
592
[ec2-user@ip-172-22-28-102 ~]$ sudo ls /proc/32085/fd | wc -l
592

Same if i go to the thread directly from under /proc/ .

Thx

Upvotes: 2

Views: 1128

Answers (3)

Michael Yuniverg
Michael Yuniverg

Reputation: 107

I've just ran across this difference today, the explanation is that lsof takes into account more types of files, like memory-mapped objects, run-time libraries etc

Upvotes: -1

Luis Colorado
Luis Colorado

Reputation: 12708

The only reason you can receive that message is that you have opened files and you didn't close them after use. You have a file descriptor leak in your java application. Java programmers normally don't check memory as the garbage collector copes with unreferenced objects. If you save file descriptors without closing in some data structure or you don't close the files after using, you can reach the maximum limit allowed to a process (this is controlled per process and can be changed by the ulimit shell command)

But if your problem is a file descriptor leak, pushing up the ulimit will only delay the problem some time. File descriptors must be closed, or you'll run into trouble.

Upvotes: 0

larsks
larsks

Reputation: 312410

Is there a way to know from the proc stat info which thread created which file descriptor?

I am pretty sure the answer here is "no". File descriptors are opened by processes, not threads (and will be visible to all threads spawned by the same process).

Why the following commands do not give the same output?

First, the -a argument to lsof appears to be a no-op in this case. Specfically, the man says that it "causes list selection options to be ANDed, as described above". So you are really just running:

sudo lsof -p 32085

And that will print things other than open file descriptors (such as memory-mapped files, current working directory, etc), while /proc/<PID>/fd contains only open file descriptors. So you're getting different results because you're asking for different information.

Upvotes: 5

Related Questions