4 ms·
But there is still no nice way to embed structures "flat" in arrays or other structures, right? If there was, I'd consider switching to Java as my main programm
by jstimpfle 4y ago
But there is still no nice way to embed structures "flat" in arrays or other structures, right? If there was, I'd consider switching to Java as my main programming language.
I don't understand much about the theory and practice of implementing a GC'ed language, but I figure the problem is "locking" such an embedded object, because it doesn't have an obvious reference. One could take its enclosing object's reference but I suppose that leads to complications. What about functions that need a pointer to an embedded object in order to read or write to it? etc.
I've had only short encounters with Java, but it (OpenJDK) did bite me in 2016, when I had to process millions of entities. I'd often run into low-memory situations and my machine would completely lock up for a minute or so, before the GC would give up and terminate the process. There was no nice way to solve the issue, other than allocating all my entities SOA style. This helped with the GC problem since it reduced my GC object count from #entities to #columns. But it isn't nice to read/write the code like that, nor is it good for the cache splitting up every little integer.
I hear that GC's have improved much recently, removing the performance issues almost entirely. However, I believe the problem remains that a lot of code is harder to write because you can't simply pass a pointer + length to a function or do a memcpy. I figure this is one reason why there is so much abstraction in Java, with proxy objects and virtual methods and the like.
If the "embedding" problem did not exist, there might not even be such a great need for GC rocket science, because there was a lot less need to have millions of objects in the first place.
- eurasiantiger 4y agoIf your structures are simple data with no methods, serialize them to BSON and store them as String. I’m half-joking, unfortunately.
- kaba0 4y agoThese are called value types, and there isn’t really a problem with them if you start from scratch, but it is very far from trivial to introduce it in a backwards compatible way plus solve it with generics in mind etc. The current plan for Java is to divide the objects into 3 buckets, one being the current ones, they are distinct from the others in having identity. The second group looses their identity, but they will retain their nullability. A great example for that would be the java.time package with e.g. LocalDate. Here two instance with the same fields will be semantically equal and replaceable, but there is no meaningful zero value as there is with numbers. If they would auto-initialize to 1970 that would probably cause some serious, hard to debug bugs later on. So they retain their nullability and they are tear-free. At initialization time they will only get visible in a state that is meaningful. The last group will be similar to current primitives. They have a designated zero value, and seeing them in a consistent state is not guaranteed (in java, changing an int value even under race conditions is free from introducing values out of thin air, that is only values can appear that were actually set from any thread). In case of a complex number that you are about to change in two steps, another thread is free to observe it in an inconsistent state. I really like this plan, and this way of thinking of object semantics actually helped me in other PLs as well. Do note that they don’t give any semantics on where the objects get stored, this is up to the VM implementation. In practice what it allows for is copying/flattening/stack-allocation of the second bucket, possibly with some clever encoding of null values a la Rust’s optionals. And the third group will allow for implementing custom numerics with basically no overhead.