Mailing Lists: Apple Mailing Lists
Image of Mac OS face in stamp
Re: Java7 Socket Closed Exception
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Java7 Socket Closed Exception



On a later test when the client was available again, I did more debugging.

At initial launch, the problem occurred within a minute.  Too quick.  No chance that many sockets had been made yet.  I did a heap dump with VisualVM, and looked at it.  Only 36 sockets in memory.  But I was already getting socket closed exceptions.  Heap wasn't "full" either...14MB in use.

This error only occurs on OSX Java 7.  When I changed to Java 6, it worked, no socket closed exceptions, and apparently is continuing to work as the client has not complained yet...

No one using Windows has complained about this either...OS X Java 7 is the first time this scenario has come up.

So it can't be too many sockets...the other lsof listing showing 240 sockets was from a longer running instance when it had occurred.  But since we made it occur right at app launch basically, its not related to timing or amount of sockets used.

I also thought that the limit -n doesn't apply to Java?  The "sysctl -a | grep files" was what is affecting java I thought...no?  The java app has 4300 open file handles (intentionally).  So that is more than 256...

This isn't new code either, so I am quite confident the sockets are being closed as I have disconnect routines in all my finally clauses around the socket usage.  But if there were too many sockets (which I have seen when I have a leak), then the issue is too many files open, and everything starts failing.  In this case everything seems fine, except network connections with sockets using direct sockets, or HTTPUrlConnections.

I also saw in the java console of the jblp file that it was getting exceptions for its RMI while I had VisualVM attached.

WARNING: RMI TCP Accept-0: accept loop for ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=51074] throws
java.net.SocketException: Socket closed
	at java.net.PlainSocketImpl.socketAccept(Native Method)
	at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:398)
	at java.net.ServerSocket.implAccept(ServerSocket.java:522)
	at java.net.ServerSocket.accept(ServerSocket.java:490)
	at sun.management.jmxremote.LocalRMIServerSocketFactory$1.accept(LocalRMIServerSocketFactory.java:52)
	at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:387)
	at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:359)
	at java.lang.Thread.run(Thread.java:722)

So that shows this isn't anything related to connecting outbound even as it was unable to accept a socket.

So I am thinking this is more of a OSX Java 7 bug...

So for now my only solution is to use Java 6...but how do I identify this bug and get something filed?  This seems like a fairly easy DOS attack vector of getting a server too full on handles and then everything shuts down.  For me, my product can't function at all in Java 7, and with Apple killing off Java 6 on everyones machine whether they wanted that done or not, its quite a pain to work around using java6 launch methods.

Thanks,
Ben

On Jun 5, 2013, at 4:22 AM, Moises Lejter <email@hidden> wrote:

I still would start by logging somewhere each time you say "new Socket()" and each time you say "socket.close()", to make sure those two numbers match...
HItting a limit around 240 suggests you're running into some per-process limit: when I do "ulimit -n" on a terminal on MacOSX, it tells me I can only open 256 files at once.  You could try doing a "ulimit -n 1024" on the shell that will start up your Java program (or the shell that starts up the browser that starts up...).

I think System.gc() is not guaranteed to actually trigger a garbage-collect cycle - but you could start a Java RMI server object within your application, just to get the RMI runtime initialized: it will force a garbage collect once a minute, once Java has published an RMI server object.  This would allow you to see if your problem has to do with uncollected sockets...  Or, from this page: http://stackoverflow.com/questions/1481178/forcing-garbage-collection-in-java - you might be able to do this:
  1. Open jconsole.exe
  2. Connect to the desired local Process.
  3. Go To memory tab and click perform GC.

Moises

On Jun 4, 2013, at 11:31 AM, Ben Spink <email@hidden> wrote:

To get the obvious questions out of the way first...
Are you closing your sockets when you're done with them?  Waiting/Hoping for garbage collection to reclaim your sockets for you is a bad idea...  (Symptoms would look just like what you're experiencing...).

Moises


An lsof indicated this might be the issue...

I have about 240+ of these lines:

java      7526       ff7admin 4809u     IPv6 0xbd2d651aa23b725d        0t0    TCP *:* (CLOSED)

Doesn't this indicate the socket is closed?  Does this mean there is a reference being held in memory for that closed socket so its not getting garbage collected?

Thanks,
Ben


 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Java-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

References: 
 >Re: Java7 Socket Closed Exception (From: Ben Spink <email@hidden>)
 >Re: Java7 Socket Closed Exception (From: Moises Lejter <email@hidden>)



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2011 Apple Inc. All rights reserved.