Namek Dev
a developer's log
NamekDev

Serializing Java: point at without pointers

May 19, 2017
Serializing Java: point at without pointers

A collection usually contains multiple elements. Let’s pick one element to observe it. What happens if it moves inside the collection? Or disappears from it?

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!

While observing, we can see that going deeper is a decision to change observation point. However, I would state that observation of the very same object is crucial. We’re not really interested about just anything under index 17 of “parent” array but actually the very same object we picked moments ago, even if it moves in an array or disappears from there. Then, imagine that array is sorted and our object is out of place. We still observe it’s values and want to modify one of those. How do we do that now?

Tracking

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

  1. tracking indices of the array (and how they change)
  2. cache a reference to the object and talk to the cache with a 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 a specific object was removed from array, 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 are somewhere in memory heap and are just referenced. Reference is a value internally (for Java VM) 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 to 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 for tracking contents of reference arrays.

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

Identification

The last thing to track the object and not the indices is identification. Identification is needef for differentation among multiple entities. Having the WeakReference is not enough so we need unique ID for an object.

public class TrackedObject {
    public long id;
    public WeakReference ref;
}

What’s interesting here? Tracking multiple objects at once. For instance, a user may be comparing visually two objects, in, say, two popup windows. “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, in intervals. If it’s so then notify the visual aspect of software to close popup window (that shows the object and it’s descendants) or disallow modification.

Track identified

When there is TrackedObjects there is also one other thing one 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 and the contents of subarray.

An important topic here is the performance. How to get all those values very often (like, 30 times per second) by not slowing down the profiled app/game? Would be reflection performant enough for this purpose? Or would it need some generation of bytecode instruction (like with ReflectASM)?

References

Daj Się Poznać, Get Noticed 2017, java, Serializing Java
comments powered by Disqus