Paul J. Lucas wrote:
> I've been looking at your code and thinking about it more.
> Presumeably, the GC, when it needs to reclaim memory, will look
> for the biggest objects to get rid of. However, in your code,
> it's only the Proxy objects that the GC will be able to
> reclaim since they're the only objects that are softly
> reachable. Proxy objects are small so it will likely need to
> reclaim lots of them. This will cause the associated Resources
> to be written to disk, more than is probably necessary since
> the GC doens't know that you intend on reclaiming the memory
> for the Resources.
No GC I am aware of considers object size.
For some background, Sun's implementations of GC runs something like this:
The vast majority of objects are very short lived. Objects are initally
allocated in the eden area. The allocation is very fast as it just bumps
a pointer up (well it is more complicated).
To reclaim memory from eden any objects that do still have a reference
are copied into a survivor area. When copying an object the references
in other objects to it are updated.
There are two quite small survivor areas, and surviving objects get
copied from one to the other as it runs out of memory. If not enough
memory is reclaimed out of the survivor area or an object has been
copied above a certain number of times, it gets copied to the tenured area.
The tenured area is where you have all the really old objects. GC here
is slow. The precise details are dependent upon which GC implementation
is configured.
Then there is the persistent area which has the JVMs class data and
interned strings.
GCs treat the reference in Reference objects specially. WeakReferences
will be cleared as soon as possible. SoftReferences will be cleared if
they haven't been used recently and there is little free memory
(actually the default is something like, clear if the age in seconds is
greater than the freed memory in megabytes).
When cleared the Reference (including an implementation for finalisers)
is added to a reference handler queue. A thread handling the queue runs
at highest priority and feeds the user reference queues and the
finalizer queue. A special type of object gets to run a finaliser type
method in the reference handler thread for efficiency.
Finalisers can then be run in finaliser threads (also running at max
priority) and ReferenceQueues can pass on the dead References.
So, no size doesn't matter. How would you calculate size anyway? What
matters is age and last use of SoftReference (I didn't show in my code,
but you have to call get on the SoftReference itself to mark as a use).
Tom Hawtin
--
Unemployed English Java programmer
http://jroller.com/page/tackline/