java.lang.ref.WeakReference is not serializable?

I get "Error serializing object" error, when I try to serialize java.lang.ref.WeakReference.

The object is not declared as serializable. It does not have default constructor, therefore inherited class also cannot be serialized.

// this does not help

class WeakReferenceSer extends WeakReference implements Serializable {

public WeakReferenceSer(Object referent) {

super(referent);

}

}

Any ideas?

[450 byte] By [choze] at [2007-9-30 20:42:31]
# 1

Implement your own writeObject and readObject methods in a derived class. But what's the point of serializing a weak reference anyway ? It's entitiled to expire during the course of serialization/deserialization anyway! You might as well just write a collection of nulls...

Oh, and see the JavaDocs for Serializable for specifics on when serialization is and isn't permitted.

Dave.

dcminter at 2007-7-7 1:31:27 > top of Java-index,Core,Core APIs...
# 2
You could use a proxy object that is serializable, and manages the WeakReference appropriately.Still seems a bizarre thing to want to do, though.Sylvia.
sylviae at 2007-7-7 1:31:27 > top of Java-index,Core,Core APIs...
# 3

I solved the problem by aggregating WeakReference into new object and serializing only WeakReference content, not object itself.

public class WeakReferenceSer implements Serializable {

private WeakReference wr;

public WeakReferenceSer(Object referent) {

wr = new WeakReference(referent);

}

public Object get() {

return wr.get();

}

/**

* Write only content of WeakReference. WeakReference itself is not seriazable.

* @param out

* @throws java.io.IOException

*/

private void writeObject(java.io.ObjectOutputStream out) throws IOException {

out.writeObject(wr.get());

}

/**

* Read saved content of WeakReference and construct new WeakReference.

* @param in

* @throws IOException

* @throws ClassNotFoundException

*/

private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {

wr = new WeakReference(in.readObject());

}

}

choze at 2007-7-7 1:31:27 > top of Java-index,Core,Core APIs...
# 4
Why did you want to do this anyway? I'm curious.Dave.
dcminter at 2007-7-7 1:31:27 > top of Java-index,Core,Core APIs...
# 5

I have object, which have a child object. Child object also have reference to parent. This is circle reference.

Garbage collector have hard times to dispose such as objects, when there is large amount of them. So I used WeakReference to reduce the circle reference. It really helps.

Child object holds WeakReference of its Parent. When there are no other regular (Strong or soft) references to Parent, WeakReference sets to null. This allows the objects to be garbage collected.

And finally, I need this structure serialize.

Simple example:

class Parent {

Child child;

}

class Child {

WeakReference parentRef;

Parent getParent() {

return (Parent) parentRef.get();

}

setParent(Parent p) {

parentRef = new WeakReference(p);

}

}

choze at 2007-7-7 1:31:27 > top of Java-index,Core,Core APIs...
# 6

> Garbage collector have hard times to dispose

> such as objects, when there is large amount

> of them. So I used WeakReference to reduce

> the circle reference. It really helps.

Is this something you've actually benchmarked? I've worked with classes that had this sort of structure and large numbers of objects and didn't encounter any problems with garbage collection...?

Dave.

dcminter at 2007-7-7 1:31:27 > top of Java-index,Core,Core APIs...
# 7

By definition a WeakReference object is one which is easily discarded

It can be discarded every time the GC runs which may be just a few seconds.

If you are trying to persist or transfer such an object, you may have a design problem.

BTW: The GC can clean up objects which have circular references. Use don't need to use WeakReferences in this situation. Note: LinkedList, LinkedHashMap and many other classes use circular references without problem.

BTW: You may wish to use SoftReferences, these don't get cleaned every time but only when the GC needs more memory.

Peter-Lawrey at 2007-7-7 1:31:27 > top of Java-index,Core,Core APIs...
# 8

I know GC can dispose objects, which have circular reference. But in our project, this did not work well. May be it's because of huge amounts of value objects (J2EE application), which were circular referenced each to other. Every time I did a operation, new objects were created (sometimes thousands), and after completed, certain amout of them remained in memory and were not disposed ever. Memory was raising constantly.

WeakReference helped. All of the objects dispose now. So this is my benchmark :-)

choze at 2007-7-7 1:31:27 > top of Java-index,Core,Core APIs...
# 9

> Every time I did a operation, new objects were

> created (sometimes thousands), and after completed,

> certain amout of them remained in memory and were

> not disposed ever. Memory was raising constantly.

This is wrong in so many ways.

Firstly, from the operating system's perspective, Java never gives memory back. So if this was the symptom, it's completely bogus.

Secondly, you'll never run out of memory because of a problem with garbage collection. The GC is absolutely guaranteed to free up any outstanding candidates for collection before it gives up and reports OutOfMemory.

Thirdly, constantly raising memory is a sign of - a bug. In your code. You're storing objects that you don't release.

If making your parent-reference entries into WeakReference objects solves the problem, then the cause of the problem must be that you were null-*** references to child objects, but not null-*** the childrens' references to their parents, and not nulling remaining references to the parent objects themselves. Probably because you had put parent object(s) into the session scope or a static variable, or somesuch.

> All of the objects dispose now. So this is

> my benchmark :-)

Actually they don't. Your fix will work to some extent, but it's a hack - you're still leaking objects, but fortunately they're WeakReference objects which are relatively small. That may be acceptable for your purposes, but you should at least be aware of this.

Dave.

dcminter at 2007-7-7 1:31:27 > top of Java-index,Core,Core APIs...
# 10

If I get it correctly you have some double-linked structure, where 'forward' links are normal java pointers, while 'backward' links are WeakReference's? This is quite ok, there're uses for this beyond optimization. At serialization tme you just declare you WeakReference's as transient, so they don't get serialized at all; at deserialization time each object owning 'forward' link should restore 'backward' link to itself (you should implement readObject method calling defaultReadObject first, and then calling iAmHere(this) for every of it's 'forward' links). Of course weak-reachable objects will not get serialized, in my example this was a feature, not a bug :) If you want to serialize the whole graph you'll have to start from some top level object, I hope you have it.

marat_khalili at 2007-7-7 1:31:27 > top of Java-index,Core,Core APIs...