JDK-4017232 : target stays pinned after DGC acknowledgement failure
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.rmi
  • Affected Version: 1.1
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: solaris_2.5
  • CPU: sparc
  • Submitted: 1996-12-02
  • Updated: 2016-02-02
  • Resolved: 2001-06-26
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.4.0 beta2Fixed
Related Reports
Relates :  
Description
If the channel fails without getting the DGCAck, the local refs the DGCAckHandler was carrying are let go of, but the Target in the ObjectTable never gets unpinned, so the implementation object still could not get collected locally.

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: merlin-beta2 FIXED IN: merlin-beta2 INTEGRATED IN: merlin-beta2 VERIFIED IN: merlin-beta2
14-06-2004

EVALUATION The occurrence of this is pretty rare. In order to fix this problem, the DGC would have to keep track of which references were making the transition from being unpinned to pinned, and if the ack (or dirty) was not received, then the target should be unpinned. --- There was not enough time to fix this bug for Cricket (1.2.2 or 1.2.1). I would also like to note that a similar "problem" can occur when a reference to a remote object is marshalled out from its own VM, and thus the target gets pinned, but the receiving endpoint never makes a successful dirty call: until more DGC activity occurs for the remote object, it will be pinned forever. Again, this will only happen in failure situations. peter.jones@East 1999-02-19 Perhaps the automatic "pinning" of remote implemention objects when their LiveRefs get marshalled out should be re-thought, with the approaches used for JSR-78 as a guide. For example, see rmi-dev message with subject "Re: more on DGC" from 11-8-2001. First off, there is a related bug that remote objects should never need to be pinned when marshalled as method arguments. Pinning is only helpful when marshalling a remote object as a return value, because otherwise, the remote object might be garbage collected before the DGC message arrvies from the client-- note that the "local" LiveRef associated with the DGC acknowledgment doesn't help out here, because it's not registered with the local DGCClient, nor does it pin the remote object by any other means (in other words, the DGC acknowledgment is rather pointless in the case of marshalling "local" LiveRefs). The approach that the JSR-78 implementation took was to only pin/unpin remote objects in response to DGC dirty/clean messages and lease expirations, which is a cleaner pinning model because it does not have to worry about the unmatched pin that is the subject of this bug report. Because it did not support implicit impl-to-stub replacement, JSR-78 had no direct concern with returned remote objects getting accidentally garbage collected. Instead, it took care to make sure that "local" DGC-enabled ObjectEndpointImpl's contained a strong reference to their corresponding remote object (although this approach had other issues; see 4404391). Therefore, the DGC acknowledgment mechanism was sufficient to protect the referential integrity of return values. For J2SE RMI, here's a proposal that addresses the above-mentioned bugs and takes a lesson from the JSR-78 approach: In LiveRef.write, never use the Target.pinImpl mechanism to pin the corresponding remote object-- leave that for DGC dirty messages only. Also, don't bother registering a "local" LiveRef for a DGC acknowledgment. Also, don't do anything along these lines unless the ConnectionOutputStream is a "result stream". Instead: If the ConnectionOutputStream is a "result stream", then if the LiveRef is not "local", then register it for a DGC acknowledgement as usual; otherwise, register the remote implementation object *itself* for being held on to until the DGC acknowledgement is received-- effectively pinning it a different way, a way that has to deal with the problem of missing acknowledgments anyway, so we might as well handle both such cases in a uniform fashion. This leaves the remaining issue that the DGCAckHandler class will hang on to the objects registered with it forever is the acknowledgment is never received. Because the RMI server in general has no way of determining if a previous client is still alive (the DGC leasing mechanism doesn't help here, because presumably no dirty message has been received yet-- and normal calls do not have VMIDs anyway), the simplest solution is to use a timeout: a given DGCAckHandler will only hold on to the objects registered with it for some fixed period of time. One question is when to start the timer? How long could it take to marshal the entire return value? There is no clear indication of when a ConnectionOutputStream is "done"; perhaps the timeout just needs to be long enough (remember that in non-failure situations, the acknowledgment should be received in a timely fashion anyway)... peter.c.jones@east 2001-05-03 This bug has been fixed as suggested above in the RMI integration workspace, probably to be integrated into Merlin Beta Refresh. peter.c.jones@east 2001-06-14
03-05-2001