orig synopsis: "java.lang.ref.ReferentQueue Feature Request"
second version: "Feature Request: java.lang.ref.ReferentNContextsQueue"
Name: krT82822 Date: 01/17/2000
1.2.2 its a Feature Request
Note: Recently I have sent you a feature request and got from you:
"Your report has been assigned an internal review ID of: 100019"
That feature request is a solution to only part of the problem and serves
as an introductory here, in Chapter 1.
I have developed that introductory idea a bit further and got to
what I present here, in chapter 2, which solves the whole problem.
Feature Request: java.lang.ref.ReferentNContextsQueue
--------------------------------------------
The Situation today:
-------------------
I find java.lang.ref missing the ability to process
ignorant object referent, when they become not strongly
reachable.
Say you want to softly refer to some object obj,
which doesn't care about you, and don't have a
finalize that take your cause under consideration.
When that obj dies you don't have the ability to
inspect it, so you can not do statistics calculations
about it and you can't serialize it, in case you wanted
to etc.
Beside that, even if your object is aware of you and does
take your cause under consideration in its finalize(),
there is still that time between the moment it has become
not-reachable and the time it would be finalized and maybe
put on a queue to wait for its inspection. In all of which it
is unreachable by the Reference, and the usual way the program
works. That time cause major synchronization problems.
The following will show how the problem may be solved:
Chapter 1 - Introduction to the concept of ReferentQueue
=======================================================
My Proposal:
I would suggest introducing a ReferentQueue which
would hold obj before it dies.
For that cause I also introduce an additional state of
a Reference: clearable. A Reference may be cleared only
if it is in the clearable state.
Entering the clearable state:
----------------------------
( First the Reference is not-clearable. )
When a Reference referent become not strongly reachable the
GC will add the referent to the ReferentQueue, where it
is strongly reachable, and change the Reference state to clearable.
Exiting the clearable state:
----------------------------
( First the Reference is clearable. )
If the referent will be accessed using the References
get() method its state will change to not-clearable again.
That is because Reference is used to implement some kind
of a cache reference to objects. Having the cache accessed
means the object is in regular use again. Therefor the
Reference must stay.
Actually Clearing
-------------
If a Reference is clearable and its referent not strongly
reachable it may be cleared.
If the get() method has not been invoked and
the referent becomes not strongly reachable again(*), then
the GC will detect References referent to be not strongly reachable
and clearable. Under these conditions References will be cleared.
( (*) ReferentQueue lost its reference of the referent by
dequeueing and the referent inspection is done and
references to it are lost. )
Analysis
========
The Reference class is usually used for referring to
objects without preventing them from being
reclaimed by the GC.
My proposal does prevent it from being reclaimed
until it has been processed. But it does give the
programmer an opportunity to inspect ignorant
objects, when the object is registered with a
ReferentQueue.
The algorithm operate by welcoming two
possibilities for the referent obj:
A. obj becomes not strongly reachable. It is
enqueued to its ReferentQueue and all References
to obj become clearable. The program uses the
ReferentQueue and obj, and eventually obj becomes
not strongly reachable. Now all References to obj
are beeing cleared and may be put on a ReferenceQueue.
At this time obj is lost by the Reference mechanism.
B. obj becomes not strongly reachable. It is
enqueued to its ReferentQueue and all References
to it become clearable. Now something in the program
access obj through a Reference, making it not-
clearable and so prevent the possibility of it being
cleared. Now for the References to obj to become
clearable again, it will have to become not strongly
reachable again.
Note the difference between getting obj from a
Reference which means that you use it in the usual
way of the program and accessing it from the
ReferentQueue which means inspection of obj before
it will be cleared.
Epilog
======
I don't know the implementation of the GC, but it seems to
me it all can be done by adding one boolean for the clearable
state checking in the Reference class and one queue for the
referents.
Beside that, the usual mechanism of the GC seems to be doing all
the work: detecting strongly referenced object, and other ranks
reachable object, which is enough for knowing which object to add
to the ReferentQueue.
The current SoftReference and WeakReference classes may be used
again with an additional ability to register with a ReferentQueue
the constructor will look like:
public SoftReference( Object referent,
ReferenceQueue referenceQueue,
ReferentQueue referentQueueu );
The ability to tell whether the Reference is clearable
might be useful as well:
public boolean is_clearable();
And the difference between soft and weak will be as always:
weak are cleared when they can be, soft are cleared when they
can be and the GC feels like clearing them.
Chapter 2 - Extending the previous idea to deal
========= with the totally ignorant object.
================================
Totally ignorant objects and context
===================================
The text above describes how to inspect the referent before it
dies. That kind of inspection is important if one does statistics
analysis of the objects and needs only the data which is in them.
However, most object has a context to them. For example: A persistent
object which needs to have an object number ID, so when it dies it could
be saved under the same number. Or a program that test the time some
objects live, when they are created it need to have the birth Date so when
it dies the inspection could calculate the age of the object on death.
For these and other reasons some referents needs a context, which will
get with them to the ReferentQueueu. One can now say "well simply put
the context in the referent object and inspect it in the ReferentQueue".
But that would be wrong, because a totally ignorant object wasn't written
to suit your cause. So it doesn't know it is persistence. It doesn't
know you measure its lifetime. etc.' .
So there is a need for a Reference class which holds another Object
which represent the context: { Object context; } one can call this
class ContextSoftReference, and ContextWeakReference.
Operation
=========
As before with the ReferentQueue, now there would be a
ReferentNContextsQueue
which will hold tupples of { referent, contexts_set } which is the referent
and a Set containing all contexts of the referent. These contexts would be
found at the ContextWeakReferences which refers to the referent.
lets call the { referent, contexts_set } tupple ReferentNContexts
The algorithm will operate in the same way as before, with one difference:
When it has been determined that the referent of the Reference needs to
be enqueued, the referent will be put in a ReferentNContexts as the referent
and the context form the ContextWeakReferences will be inserted into the
contexts_set of ReferentNContexts object. Now after all ContextWeakReference
referring to that referent has been examined and their contexts added to the
contexts_set, this ReferentNContexts object will be enqueued to the
ReferentNContextsQueue.
Now when the user will want to examine the objects that are near their end,
the user will just need to dequeue form the ReferentNContextsQueue, get
the referent and evaluate it with each of the contexts in the contexts
set.
I have already given some examples of what context might be, but I think
there are a lot of other example, because this mechanism is really flexible
and lets the user define what the context will be. Whether just a Long
with the birth-date, an object number ID, or even a special context
class which has an interface for processing the object, in which case many
classes could be directed to the same queue for processing.
Epilog
======
This development also looks to me very easy to implement, after all
if the GC can clear when it finds the referent not-strongly-reachable
it can also get a context from the Reference and put it in a contexts_set.
The constructor will look like:
public ContextWeakReference( Object referent,
ReferenceQueue referenceQueue,
Object context,
ReferentNContextsQueue referentNcontextsQueue);
The ability to tell whether the Reference is clearable
might be useful as well:
public boolean is_clearable();
And beside that the API is like for a usual Reference subclass.
This new classes can do the job of the ReferentQueue by giving a null
context. This class is much more useful then Chapter 1's.
ContextWeakReference and ContextSoftReference should be implemented.
After that I am not sure if the class that is in Chapter 1 is necessary.
Though it doesn't hurt to have it as well.
(Review ID: 100068)
======================================================================
second version: "Feature Request: java.lang.ref.ReferentNContextsQueue"
Name: krT82822 Date: 01/17/2000
1.2.2 its a Feature Request
Note: Recently I have sent you a feature request and got from you:
"Your report has been assigned an internal review ID of: 100019"
That feature request is a solution to only part of the problem and serves
as an introductory here, in Chapter 1.
I have developed that introductory idea a bit further and got to
what I present here, in chapter 2, which solves the whole problem.
Feature Request: java.lang.ref.ReferentNContextsQueue
--------------------------------------------
The Situation today:
-------------------
I find java.lang.ref missing the ability to process
ignorant object referent, when they become not strongly
reachable.
Say you want to softly refer to some object obj,
which doesn't care about you, and don't have a
finalize that take your cause under consideration.
When that obj dies you don't have the ability to
inspect it, so you can not do statistics calculations
about it and you can't serialize it, in case you wanted
to etc.
Beside that, even if your object is aware of you and does
take your cause under consideration in its finalize(),
there is still that time between the moment it has become
not-reachable and the time it would be finalized and maybe
put on a queue to wait for its inspection. In all of which it
is unreachable by the Reference, and the usual way the program
works. That time cause major synchronization problems.
The following will show how the problem may be solved:
Chapter 1 - Introduction to the concept of ReferentQueue
=======================================================
My Proposal:
I would suggest introducing a ReferentQueue which
would hold obj before it dies.
For that cause I also introduce an additional state of
a Reference: clearable. A Reference may be cleared only
if it is in the clearable state.
Entering the clearable state:
----------------------------
( First the Reference is not-clearable. )
When a Reference referent become not strongly reachable the
GC will add the referent to the ReferentQueue, where it
is strongly reachable, and change the Reference state to clearable.
Exiting the clearable state:
----------------------------
( First the Reference is clearable. )
If the referent will be accessed using the References
get() method its state will change to not-clearable again.
That is because Reference is used to implement some kind
of a cache reference to objects. Having the cache accessed
means the object is in regular use again. Therefor the
Reference must stay.
Actually Clearing
-------------
If a Reference is clearable and its referent not strongly
reachable it may be cleared.
If the get() method has not been invoked and
the referent becomes not strongly reachable again(*), then
the GC will detect References referent to be not strongly reachable
and clearable. Under these conditions References will be cleared.
( (*) ReferentQueue lost its reference of the referent by
dequeueing and the referent inspection is done and
references to it are lost. )
Analysis
========
The Reference class is usually used for referring to
objects without preventing them from being
reclaimed by the GC.
My proposal does prevent it from being reclaimed
until it has been processed. But it does give the
programmer an opportunity to inspect ignorant
objects, when the object is registered with a
ReferentQueue.
The algorithm operate by welcoming two
possibilities for the referent obj:
A. obj becomes not strongly reachable. It is
enqueued to its ReferentQueue and all References
to obj become clearable. The program uses the
ReferentQueue and obj, and eventually obj becomes
not strongly reachable. Now all References to obj
are beeing cleared and may be put on a ReferenceQueue.
At this time obj is lost by the Reference mechanism.
B. obj becomes not strongly reachable. It is
enqueued to its ReferentQueue and all References
to it become clearable. Now something in the program
access obj through a Reference, making it not-
clearable and so prevent the possibility of it being
cleared. Now for the References to obj to become
clearable again, it will have to become not strongly
reachable again.
Note the difference between getting obj from a
Reference which means that you use it in the usual
way of the program and accessing it from the
ReferentQueue which means inspection of obj before
it will be cleared.
Epilog
======
I don't know the implementation of the GC, but it seems to
me it all can be done by adding one boolean for the clearable
state checking in the Reference class and one queue for the
referents.
Beside that, the usual mechanism of the GC seems to be doing all
the work: detecting strongly referenced object, and other ranks
reachable object, which is enough for knowing which object to add
to the ReferentQueue.
The current SoftReference and WeakReference classes may be used
again with an additional ability to register with a ReferentQueue
the constructor will look like:
public SoftReference( Object referent,
ReferenceQueue referenceQueue,
ReferentQueue referentQueueu );
The ability to tell whether the Reference is clearable
might be useful as well:
public boolean is_clearable();
And the difference between soft and weak will be as always:
weak are cleared when they can be, soft are cleared when they
can be and the GC feels like clearing them.
Chapter 2 - Extending the previous idea to deal
========= with the totally ignorant object.
================================
Totally ignorant objects and context
===================================
The text above describes how to inspect the referent before it
dies. That kind of inspection is important if one does statistics
analysis of the objects and needs only the data which is in them.
However, most object has a context to them. For example: A persistent
object which needs to have an object number ID, so when it dies it could
be saved under the same number. Or a program that test the time some
objects live, when they are created it need to have the birth Date so when
it dies the inspection could calculate the age of the object on death.
For these and other reasons some referents needs a context, which will
get with them to the ReferentQueueu. One can now say "well simply put
the context in the referent object and inspect it in the ReferentQueue".
But that would be wrong, because a totally ignorant object wasn't written
to suit your cause. So it doesn't know it is persistence. It doesn't
know you measure its lifetime. etc.' .
So there is a need for a Reference class which holds another Object
which represent the context: { Object context; } one can call this
class ContextSoftReference, and ContextWeakReference.
Operation
=========
As before with the ReferentQueue, now there would be a
ReferentNContextsQueue
which will hold tupples of { referent, contexts_set } which is the referent
and a Set containing all contexts of the referent. These contexts would be
found at the ContextWeakReferences which refers to the referent.
lets call the { referent, contexts_set } tupple ReferentNContexts
The algorithm will operate in the same way as before, with one difference:
When it has been determined that the referent of the Reference needs to
be enqueued, the referent will be put in a ReferentNContexts as the referent
and the context form the ContextWeakReferences will be inserted into the
contexts_set of ReferentNContexts object. Now after all ContextWeakReference
referring to that referent has been examined and their contexts added to the
contexts_set, this ReferentNContexts object will be enqueued to the
ReferentNContextsQueue.
Now when the user will want to examine the objects that are near their end,
the user will just need to dequeue form the ReferentNContextsQueue, get
the referent and evaluate it with each of the contexts in the contexts
set.
I have already given some examples of what context might be, but I think
there are a lot of other example, because this mechanism is really flexible
and lets the user define what the context will be. Whether just a Long
with the birth-date, an object number ID, or even a special context
class which has an interface for processing the object, in which case many
classes could be directed to the same queue for processing.
Epilog
======
This development also looks to me very easy to implement, after all
if the GC can clear when it finds the referent not-strongly-reachable
it can also get a context from the Reference and put it in a contexts_set.
The constructor will look like:
public ContextWeakReference( Object referent,
ReferenceQueue referenceQueue,
Object context,
ReferentNContextsQueue referentNcontextsQueue);
The ability to tell whether the Reference is clearable
might be useful as well:
public boolean is_clearable();
And beside that the API is like for a usual Reference subclass.
This new classes can do the job of the ReferentQueue by giving a null
context. This class is much more useful then Chapter 1's.
ContextWeakReference and ContextSoftReference should be implemented.
After that I am not sure if the class that is in Chapter 1 is necessary.
Though it doesn't hurt to have it as well.
(Review ID: 100068)
======================================================================