I came across C24's SDO the other day. It takes a very different approach to dealing with the problems of stop-the-world GC and memory bloat. It uses code generation to allow accessors to a compressed byte array with natural getters and setters as well as operations on the data, so it can represent large, complex objects with the minimum possible memory footprint.
Classic object-oriented programming teaches you to think of objects as data combined with the operations you can perform on that data, or as entities to which you can send messages through their interface. But there is a third way to think of them, and SDO in a way takes this approach: objects are views.
In this case what is being viewed is the memory allocated to that object. SDO takes the radical approach of bit-packing that memory space, but you could just as well think of the class as providing a view on memory image of a Java object in the heap whatever the layout. "Viewing" could mean getting a field, getting a composed child object, or it could mean executing an operation on memory.
This way of thinking about objects is particularly useful for value objects. For classic OO, value objects are an embarrassment. JavaBeans with getters and setters break encapsulation and are dead objects, providing no real operations other than to read and write data: little better than C-style structs. But they are all over the place because any time we acquire data from a database or through a messaging layer we do not want to be constantly re-parsing the content. We want meaningful, typesafe accessors, and so we build value objects around them. In short: we want a typesafe view on the data.
Why does this matter? If you have a billion records, you do not need a billion objects. You need only as many objects as you have instances that are being manipulated in live threads. We want to make choices; perform calculations; and take actions using the data: we are mapping to objects to do map/reduce operations. Converting an LDAP directory record into a Person object, say, is usually not the goal; it is just a means of getting at the first and last name fields without having to sprinkle our code with direct references to the attribute names in our LDAP schema. If we could iterate through every person record in a company without instantiating objects for all of them, of course we would prefer this. And if we could use a typesafe object for this purpose, again, of course we would prefer this.
This applies to many problems where we are dealing with a firehose of data and want to avoid creating garbage: an incoming FIX execution report; a marketdata tick; a large number of records from an analytic dataset; etc.. We want to get views onto these messages and records, but don't want to instantiate an object every time, and wearing our OO hats, ideally if the consumer is only reading that data, we do not want to expose the setter methods needed to set all the fields, and we don't want a massive constructor with 50 different parameters either.
So I wonder: with many good toolkits for generating code on-the-fly and Java 8 default methods providing a means to put operations on an interface, is it possible to write a functional interface and generate code that does the work of binding, and puts the data behind it only as it streams past? i.e. could we generate a view that's separate from the memory it's viewing, and allow much more scalable systems? And could we make that work with pooling and recycling so these lightweight viewing objects are kept to a minimum?
There are elements of SDO that I do not like as a programming model, but I think C24 is onto something: part of the problem with writing zero-GC problems is about how we represent the objects themselves.