Serializing Java: point at without pointers

Collection usually contains multiple elements. We pick one to observe it. But what if it moves inside the collection?

This is Serializing Java – emerging series about writing your own serializer in case you didn’t like other serializers.

Observation

Let’s talk about some array of objects. Having a list of this array’s elements is some observation of the array. Let’s pick an index = 17. Seems that  array[17]  is not null, it’s an object. Let’s observe it then!

We see that going deeper is a decision of change of our observation point. I state that observation of the very same object is crucial. We’re not really interested about anything under index 17 of “parent” array. Then, visualize that array is sorted and our object is out of place. It’s got another index but we’re not much interested in that fact. We still observe it’s values and want to change on of it. How do we do that now?

Tracking

We need to track that object. I can see only these options:

  1. tracking indices of the array
  2. cache a reference to the object and talk to the cache with an identifier created for that object only

Tracking array indices

Tracking indices seems to be pretty hard, I must say. We would need to rescan the array on some events or with intervals. To detect that this object was lost we could assume that if it’s not in this array anymore then it’s dead. However, this is not correct assumption since object is really somewhere in memory and array contains only a reference. So, there could be multiple references to the same object.

But, I have to admit that index tracking would be useful in a visual aspect.

Java has no pointers

It’s not C++ so it does not have pointers. Pointers are cool because those are serializable – you can simply remember it as a number or stream of bits. In Java objects lie in memory and are just referenced. Reference is a value but it’s not serializable. However, there are tools to keep object references in memory – safely.

What you mean “safely”? Yeah, we should not hide any real object from garbage collection. We inspect it’s state but we shouldn’t modify it (because of memleaks).

That saying we can keep our references in:

  • SoftReference
  • WeakReference
  • PhantomReference

There also exists a StrongReference but it works in the opposite way – it prevents GC work.

Phantom references are useful to just find out if object is really dead. However, it always returns null, whenever we ask about it. It’s because it’s very close to GC itself. Now, we should ask ourselves about the implementation of tracking here. May be an option.

What I needed was WeakReference because it holds a reference and allows to collect an object in a first pass. SoftReferences delays collection a little, I have no value in it.

Identify

Last thing to track the object and not the indices is identification. Having WeakReference is not enough so we need unique ID for object.

What’s interesting here? Tracking multiple objects at once. For instance, a user may be comparing visually two objects. “Two or more, use a for” as they say. We have to track nulls. I guess there is no other way than checking whether  ref contains null by interval. If it’s so then notify the visual aspect of software to close window or disallow modification.

Track identified

When you have TrackedObjects there is also one other thing you might want to do. Taking snapshots for showing the state of object.

And here comes a big question – how to show difference between two snapshots to visualise changes of object state? Seems easy if you think only about fields. But what if one of fields is an array? Would you also follow this array? This issue brings us back to tracking indices.

Another interesting issue is performance. How to get all those values very often (like, 30 times per second)? Would be reflection enough? Or would it need some generation of bytecode instructions (like with ReflectASM)?

References