NSConnection/NSSocketPort per-subthread Mach port leak
NSConnection/NSSocketPort per-subthread Mach port leak
- Subject: NSConnection/NSSocketPort per-subthread Mach port leak
- From: Kirk Kerekes <email@hidden>
- Date: Fri, 14 Jul 2006 11:46:43 -0500
RE: <rdar://problem/4621753>
It appears that using a NSSocketPort-based Distributed Object's
rootProxy in a thread other than the one the NSConnection was created
in leaks 3 Mach ports for each distinct thread that uses the rootProxy.
• The ports are not released when the thread exits -- they are only
released when the application terminates.
• The leak appears to be per-thread, not per-access.
• I have only investigated this issue with NSSocketPort.
• I have only investigated this on the "client" side of an NSConnection.
NOTE: you can conveniently track Mach port counts with Activity
Monitor's "#Ports" column.
This isn't a big issue with apps that are terminated regularly or
that use Distributed Objects sparingly, but I was forced to
investigate this by a continuously-running app that makes many
thousands of NSSocketPort DO calls daily to a remote host and which
would bring the OS (on the client machine) to its knees in a day or
two due to this leak.
Restructuring the application to eliminate the use of transient sub-
threads sharing an NSConnection eliminated the problem entirely.
The restructuring combined both of the non-leaking scenarios
discussed in "Scenarios that effectively do _not_ leak:" below.
Specifics:
If you have a scenario where you establish a connection in the main
thread, and then pass that connection's rootProxy to multiple
transient sub-threads (after setting multipleThreadsEnabled), any use
of that rootProxy in a given sub-thread allocates 3 Mach ports that
are not released when the thread exits. AFAIK these ports are only
released when the application terminates.
I have not been able to find any way to prevent this while preserving
the overall scenario -- the only "fix" has been to change the program
design to avoid the repetitive use of transient threads that share a
NSConnection/NSSocketPort.
I assume that this leak has to do with whatever
multipleThreadsEnabled does to allow multi-thread access, but that
assumption has not led me to a successful "fix" that does not involve
avoiding the leaky scenario entirely.
Summary:
Scenarios that effectively do _not_ leak:
• If you have each transient thread create/discard its own
NSConnection/NSSocketPort, no port-leak.
• If you create a single "worker" thread that persists as long as the
application does, and just waits for input from the main thread, only
one triplet (presumably) of Mach ports leaks. This shouldn't be a
problem. Apps commonly have 100-200 Mach ports allocated -- Mail.app
has 409 of them as I write this.
Scenario that leaks:
• If you create an NSConnection in the main thread, and then pass it
or its rootProxy to multiple transient subthreads, the application
will leak 3 Mach ports for each subthread in which the rootProxy is
used to access its remote rootObject.
Scenario that appears to leak but hasn't been exhaustively investigated:
• Create a NSConnection in a transient subthread, and then use it in
the main thread or other transient threads.
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden