I'm writing a high performance/low garbage application
(microseconds matter) that has a networking component. One of the sore points that I've come across is the implementation of the built in Selector for Java NIO.
A few things that are problematic:
Lots of object creation. Pretty much every call to selectedKeys() creates a lot of objects. Iterators, boxing/unboxing, you name it. Not a problem with most other cases but the application I'm writing needs to create as little garbage as possible.
Layers upon layers of locking and synchronization. At the time the selectorImpls were built, a bunch of the Java lock primitives didn't exist. As a result it's clunky and not optimal. In my use case, there's only one thread calling select so the locking is in fact useless.
Extending or changing the selector implementation is a nonstarter. Most of the classes are final, with private and package-private members located in the sun.nio.ch.* package. Native methods also complicate things.
Are there any other more modern implementations of the selector that may be more performant?
The networking libraries I've examined just use the built in Java selector under the covers. Any help would be appreciated.
Maybe this lib satisfies your needs? Haven't used it myself, but looks promising.
http://www.coralblocks.com/index.php/the-simplicity-of-coralreactor/
Netty project has an implementation that uses Native epoll edge-triggered transport:
Since 4.0.16, Netty provides the native socket transport for Linux using JNI. This transport has higher performance and produces less garbage [...]
One possible drawback for you might be, it's available on Linux only.
On the positive side, Netty is an open-source project, may be the source code will give you a hint or two.
Regarding your first point about lots of object creation, you can ameliorate by using the select methods that were introduced in java11, the ones that accept an action Consumer as a parameter.
Before java11, every time you call a select() method, you have to call iterator() to access the events. This would create a new iterator object which would be subject to garbage collection. And this was unfortunately enshrined in the interface (abstract base class) itself.
The new methods iterate over the events themselves, applying your action, and reducing garbage.
Here's the javadoc for the new methods: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/channels/Selector.html#select(java.util.function.Consumer,long)
Related
I was wondering how the serialization of MicroStream works in detail.
Since it is described as "Super-Fast" it has to rely on code-generation, right? Or is it based on reflections?
How would it perform in comparison to the Protobuf-Serialization, which relies on Code-generation that directly reads out of the java-fields and writes them into a bytebuffer and vice-versa.
Using reflections would drastically decrease the performance when serializing objects on a huge scale, wouldn't it?
I'm looking for a fast way to transmit and persist objects for a multiplayer-game and every millisecond counts. :)
Thanks in advance!
PS: Since I don't have enough reputation, I can not create the "microstream"-tag. https://microstream.one/
I am the lead developer of MicroStream.
(This is not an alias account. I really just created it. I'm reading on StackOverflow for 10 years or so but never had a reason to create an account. Until now.)
On every initialization, MicroStream analyzes the current runtime's versions of all required entity and value type classes and derives optimized metadata from them.
The same is done when encountering a class at runtime that was unknown so far.
The analysis is done per reflection, but since it is only done once for every handled class, the reflection performance cost is negligible.
The actual storing and loading or serialization and deserialization is done via optimized framework code based on the created metadata.
If a class layout changes, the type analysis creates a mapping from the field layout that the class' instances are stored in to that of the current class.
Automatically if possible (unambiguous changes or via some configurable heuristics), otherwise via a user-provided mapping. Performance stays the same since the JVM does not care if it (simplified speaking) copies a loaded value #3 to position #3 or to position #5. It's all in the metadata.
ByteBuffers are used, more precisely direct ByteBuffers, but only as an anchor for off-heap memory to work on via direct "Unsafe" low-level operations. If you are not familiar with "Unsafe" operations, a short and simple notion is: "It's as direct and fast as C++ code.". You can do anything you want very fast and close to memory, but you are also responsible for everything. For more details, google "sun.misc.Unsafe".
No code is generated. No byte code hacking, tacit replacement of instances by proxies or similar monkey business is used. On the technical level, it's just a Java library (including "Unsafe" usage), but with a lot of properly devised logic.
As a side note: reflection is not as slow as it is commonly considered to be. Not any more. It was, but it has been optimized pretty much in some past Java version(s?).
It's only slow if every operation has to do all the class analysis, field lookups, etc. anew (which an awful lot of frameworks seem to do because they are just badly written). If the fields are collected (set accessible, etc.) once and then cached, reflection is actually surprisingly fast.
Regarding the comparison to Protobuf-Serialization:
I can't say anything specific about it since I haven't used Protocol Buffers and I don't know how it works internally.
As usual with complex technologies, a truly meaningful comparison might be pretty difficult to do since different technologies have different optimization priorities and limitations.
Most serialization approaches give up referential consistency but only store "data" (i.e. if two objects reference a third, deserialization will create TWO instances of that third object.
Like this: A->C<-B ==serialization==> A->C1 B->C2.
This basically breaks/ruins/destroys object graphs and makes serialization of cyclic graphs impossible, since it creates and endlessly cascading replication. See JSON serialization, for example. Funny stuff.)
Even Brian Goetz' draft for a Java "Serialization 2.0" includes that limitation (see "Limitations" at http://cr.openjdk.java.net/~briangoetz/amber/serialization.html) (and another one which breaks the separation of concerns).
MicroStream does not have that limitation. It handles arbitrary object graphs properly without ruining their references.
Keeping referential consistency intact is by far not "trying to do too much", as he writes. It is "doing it properly". One just has to know how to do it properly. And it even is rather trivial if done correctly.
So, depending on how many limitations Protobuf-Serialization has ("pacts with the devil"), it might be hardly or even not at all comparable to MicroStream in general.
Of course, you can always create some performance comparison tests for your particular requirements and see which technology suits you best. Just make sure you are aware of the limitations a certain technology imposes on you (ruined referential consistency, forbidden types, required annotations, required default constructor / getters / setters, etc.).
MicroStream has none*.
(*) within reason: Serializing/storing system-internals (e.g. Thread) or non-entities (like lambdas or proxy instances) is, while technically possible, intentionally excluded.
Is it safe to use the javafx.util.Callback on a server machine? As I understand, and I may be wrong, not all JavaFX components are available on a server installation where graphics arent available.
Should I create my own callback interface, or just use one from javafx?
At first, I didn’t like using it either, because this interface was losing quality in my code. I no longer had self-explaining interface names. But in the end, I realized that the advantages overweigh the lack of quality. The advantages being:
We end up writing less code. No specialized interface, no default implementations.
The developer using the API does not have to remember different factories, instead, he can focus on the object that he wants to create and the parameters that are available to him.
The Callback interface is a functional interface. We can use Lambda expressions, which makes the code more elegant and we once again have to write less code.
Therefore I would suggest using javafx.util.Callback instead of custom one
I have a requirement, where support in my application a lot of processing is happening, at some point of time an exception occrured, due to an object. Now I would like to know the whole history of that object. I mean whatever happened with that object over the period of time since the application has started.
Is this peeping into this history of Object possible thru anyway using JMX or anything else ?
Thanks
In one word: No
With a few more words:
The JVM does not keep any history on any object past its current state, except for very little information related to garbage collection and perhaps some method call metrics needed for the HotSpot optimizer. Doing otherwise would imply a huge processing and memory overhead. There is also the question of granularity; do you log field changes only? Every method call? Every CPU instruction during a method call? The JVM simply takes the easy way out and does none of the above.
You have to isolate the class and/or specific instance of that object and log any operation that you need on your own. You will probably have to do that manually - I have yet to find a bytecode instrumentation library that would allow me to insert logging code at runtime...
Alternatively, you might be able to use an instrumenting profiler, but be prepared for a huge performance drop when doing that.
That's not possible with standard Java (or any other programming language I'm aware of). You should add sufficient logging to your application, which will allow you to get some idea of what's happened. Also, learn to use your IDE's debugger if you don't already know how.
I generally agree with #thkala and #artbristol (+1 for both).
But you have a requirement and have no choice: you need a solution.
I'd recommend you to try to wrap your objects with dynamic proxies that perform auditing, i.e. write all changes that happen to object.
You can probably use AspectJ for this. The aspect will note what method was called and what are the parameters that were sent. You can also use other, lower level tools, e.g. Javasist or CgLib.
Answer is No.JVM doesn't mainatain the history of object's state.Maximum what you can do you can keep track of states of your object that could be some where in-memory and when you get exception you can serialize that in-memory object and then i think you can do analysis.
I very much like the simplicity of calling remote methods via Java's RMI, but the verbosity of its serialization format is a major buzz kill (Yes, I have benchmarked, thanks). It seems that the architects at Sun did the obvious right thing when designing the RPC (speaking loosely) component, but pulled an epic fail when it came to implementing serialization.
Conversely, it seems the architects of Thrift, Avro, Kryo (especially), protocol buffers (not so much), etc. generally did the obvious right thing when designing their serialization formats, but either do not provide a RPC mechanism, provide one that is needlessly convoluted (or immature), or else one that is more geared toward data transfer than invoking remote methods (perfectly fine for many purposes, but not what I'm looking for).
So, the obvious question: How can I use RMI's method-invocation loveliness but employ one of the above libraries for the wire protocol? Is this possible without a lot of work? Am I evaluating one of the aforementioned libraries too harshly (N.B. I very much dislike code generation, in general; I dislike unnecessary annotations somewhat, and XML configuration quite a bit more; any sort of "beans" make me cringe--I don't need the weight; ideally, I'm looking to just implement an interface for my remote objects, as with RMI).
Once upon a time, I did have the same requirement. I had changed rmi methods arguments and return types to byte[].
I had serialized objects with my preferred serializer to byte array, then called my modified rmi methods.
Well, as you mentioned java serialization is too verbose, therefore 5 years ago I did implement a space efficient serialization algorithm. It saves too much space, if you are sending a very complex object graph.. Recently, I have to port this serialization implementation to GWT, because GWT serialization in Dev mode is incredibly slow.
As an example;
rmi method
public void saveEmployee(Employee emp){
//business code
}
you should change it like below ,
public void saveEmployee(byte[] empByte) {
YourPreferredSerializer serialier = YourPreferredSerializerFactory.creteSerializer();
Employee emp = (Employee) serializer.deSerialize(empByte);
//business code
}
EDIT :
You should check MessagePack . it looks promising.
I don't think there is a way to re-wire RMI, but it might be that specific replacement projects -- I am specifically thinking of DiRMI -- might? And/or project owners might be interest in helping with this (Brian, its author, is a very competent s/w engineer from Amazon.com).
Another interesting project is Protostuff -- its author is building a RPC framework too (I think); but even without it supports an impressive range of data formats; and does this very efficiently (as per https://github.com/eishay/jvm-serializers/wiki/).
Btw, I personally think biggest mistake most projects have made (like PB, Avro) is not keeping proper separation between RPC and serialization aspects nicely separate.
So ability to do RPC using a pluggable data format or serialization providers seems like a good idea to me.
writeReplace() and readResolve() is probably the best combo for doing so. Mighty powerful in the right hands.
Java serialization is only verbose where it describes the classes and fields it's serializing. Overall, the format is as "self describing" as XML. You can can actually override this and replace it with something else. This is what the writeClassDescriptor and readClassDescriptor methods are for. Dirmi overrides these methods, and so it is able to use standard object serialization with less wire overhead.
The way it works is related to how its sessions work. Both endpoints may have different versions of the object, and so simply throwing away the class descriptors won't work. Instead, additional data is exchanged (in the background) so that the serialized descriptor is replaced with a session-specific identifier. Upon seeing the identifier, a lookup table is examined to find the descriptor object. Because the data is exchanged in the background, there's a brief "warm up period" after a session is created and for every time an object type is written for the first time.
Dirmi has no way to replace the wire format at this time.
If you had the chance to significantly change/update Java's classpath libraries, which things would you add/update/change/deprecate/remove?
Restructure all the various aspects of the currently far to monolithic class library into seperate modules with lower interdependencies. This would require to seperate interfaces and provided default implementations into distinctive class hierachies (similar to what exists for the SAX API already). Rationale: allow deployments with stripped down class libraries and additionally enable third party replacementes and extensions of certain central aspects (crypto, network protocols, i18n, ...).
Redesign all collection classes and some of the java.lang classes into much smaller building blocks that can be assembled into more flexible and more powerfull data structures (along the philosophy of the Google Collections classes). This would offer far more context independant behavioural interfaces, like i.e. CharSequence or Comparable.
Provide more platform specific (Extension-)APIs and implementations that cover as much as is reasonable of the supported platforms (and grow with them) and accept that code that is using these classes will not be portable without extra effort from the developer. This is meant to allow the creation of non trivial software that is able to compete with native software in terms of usability, usefullness and general perceived quality. These APIs would for example allow access to block devices, vt100 terminals, the Windows registry etc.
Redesign Swing in a multilayered way (i.e. controls on top of basic building blocks on top of a graphics primitives API) and make it far more polymorphic. I.e a single Action interface with a single method perform instead of lots of special Listener interfaces. Additionally I'd offer a wrapper framework that encapsulates native GUI components (in the spirit of my previous proposal).
Try to find a better way to handle security related access restrictions for sandbox environments that doesn't limit the overall flexibilty of many imporatant fundamental classes. Currently language features originaly intended for design purposes are heavily abused for security purposes which has led to rather static and nonpolymorphic classes and APIs because they could be expoited from within a sandbox if they were more open (and the approach still failed to be secure enough many many times).
Provide a less naive serialization system that supports weak references, has error detection and supports class evolution.
I'd add CheckedException at the same level as RuntimeException (make it less often that people "have" to catch Exception)
I'd remove all the deprecated APIs.
I'd remove the old collection classes, like Vector and Dictionary.
I'd make a boat load of exception classes under IOException.
I'd replace as many public static final int X; constants as I could with enums.
I'd get rid of Object.hashCode and define a Hashable / Hasher interfaces instead. (But I'd retain System.identityHashCode(Object) because despite its overheads it does something very useful that is impossible to do any other way.)
I'd get rid of Object.equals and define an Equatable / Equater interfaces instead. (But with better names if I could manage it.)
I'd get rid of Object.clone. I might retain it as a method on the array classes.
I'd get rid of Object.finalize and replace it with something that naive C/C++ programmers won't notice until they are experienced enough to know that finalization is almost always the wrong solution.
I'd get rid of System.gc();
I'd replace the clunky global System.in/out/err stuff with something that used Readers/PrintWriters and that was / could easily be "scoped" by thread or threadgroup.
I'd remove the ability to take a primitive lock on any Object (... OK not strictly library change).
I'd try figure out how to implement safe versions of thread.stop/suspend/resume ... even if this meant implementing Isolates in J2SE JVMs.