When you use writeUnshared on the write side, you have already completed one half of the job. If you now use readUnshared on the input side rather than readObject , ObjectInputStream will not support object references.
You can use the following program to check the behavior:
package lib.io; import java.awt.Button; import java.io.*; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import java.util.concurrent.ConcurrentHashMap; public class ObjectInputStreamReferences { public static void main(String[] args) throws IOException, ClassNotFoundException { final int numObjects=1000; Serializable s=new Button(); ByteArrayOutputStream os=new ByteArrayOutputStream(); try( ObjectOutputStream oos=new ObjectOutputStream(os) ) { for(int i=0; i<numObjects; i++) oos.writeUnshared(s); } final ConcurrentHashMap<WeakReference<?>, Object> map =new ConcurrentHashMap<>(); final ReferenceQueue<Object> q=new ReferenceQueue<>(); new Thread(new Runnable() { public void run() { reportCollections(map, q); } }).start(); try(ObjectInputStream ois= new ObjectInputStream(new ByteArrayInputStream(os.toByteArray()))) { for(int i=0; i<numObjects; i++) { Object o=ois.readUnshared(); map.put(new WeakReference<>(o,q), ""); o=null; System.gc();Thread.yield(); } } System.exit(0); } static void reportCollections( ConcurrentHashMap<WeakReference<?>, Object> map, ReferenceQueue<?> q) { for(;;) try { Reference<?> removed = q.remove(); System.out.println("one object collected"); map.remove(removed); } catch(InterruptedException ex){} } }
source share