say I have 2 instances of the same class, but they behave differently (follow different code paths) based on a final boolean field set at construction time. so something like:
public class Foo {
private final boolean flag;
public Foo(boolean flagValue) {
this.flag = flagValue;
}
public void f() {
if (flag) {
doSomething();
} else {
doSomethingElse();
}
}
}
2 instances of Foo with different values for flag could in theory be backed by 2 different assemblies, thereby eliminating the cost of the if (sorry for the contrived example, its the simplest one I could come up with).
so my question is - do any JVMs actually do this? or is a single class always backed by a single assembly?
Yes, JVMs do this form of optimization. In your case, this would be a result of inlining and adaptive optimization for being a value to always be true. Consider the following code:
Foo foo = new Foo(true);
foo.f();
It is trivial to prove for HotSpot that Foo is always an actual instance of Foo at the call site of f what allows the VM to simply copy-paste the code of the method, thus eliminating the virtual dispatch. After inlining, the example is reduced to:
Foo foo = new Foo(true);
if (foo.flag) {
doSomething();
} else {
doSomethingElse();
}
This again, allows to reduce the code to:
Foo foo = new Foo(true);
foo.doSomething();
If the optimization can be applied does therefore depend on the monomorphism of the call site of foo and the stability of flag at this call site. (The VM profiles your methods for such patterns.) The less the VM is able to predict the outcome of your program, the less optimization is applied.
If the example was so trivial as the above code, the JIT would probably also erase the object allocation and simply call doSomething. Also, for the trivial example case where the value of the field can be proven to be true trivially, the VM does not even need to optimize adaptively but simply applies the above optimization. There is a great tool named JITWatch that allows you to look into how your code gets optimized.
The following applies to hotspot, other JVMs may apply different optimizations.
If those instances are in turned assigned to static final fields and then referred to by other code and the VM is started with -XX:+TrustFinalNonStaticFields then those instances can participate in constant folding and inlining CONSTANT.f() can result in different branches being eliminated.
Another approach available to privileged code is creating anonymous classes instead of instances via sun.misc.Unsafe.defineAnonymousClass(Class<?>, byte[], Object[]) and patching a class constant for each class, but ultimately that also has to be referenced through a class constant to have any effect on optimizations.
Related
I'm trying to get to learn more about the JVM when it comes to optimising my code and was curious whether (or more specifically in which ways) it optimises out unused fields?
I assume that if you have a field within a class that is never written too or read from, when the code is run this field will not exist within the class. Say you had a class that looked like this:
public class Foo {
public final int A;
public final float B;
private final long[] C = new long[512];
}
and you only used variables A and B, then you can probably see how initiating, maintaining and freeing variable C is a waste of time for what is essentially garbage data. Firstly would I be correct in assuming the JVM would spot this?
Now my second and more important example is whether the JVM takes inheritance into consideration here? Say for example Foo looked more like this:
public class Foo {
public final int A;
public final float B;
private final long[] C = new long[512];
public long get(int i) {
return C[i];
}
}
then I assume that this class would be stored somewhere in memory kinda like:
[ A:4 | B:4 | C:1024 ]
so if I had a second class that looked like this:
public class Bar extends Foo {
public final long D;
#Override public long get(int i) {
return i * D;
}
}
then suddenly this means that field C is never used, so would an instance of Bar in memory look like this:
[ A:4 | B:4 | C:1024 | D:8 ] or [ A:4 | B:4 | D:8 ]
To prove that a field is entirely unused, i.e. not only unused til now but also unused in the future, it is not enough to be private and unused with the declaring class. Fields may also get accessed via Reflection or similar. Frameworks building upon this may even be in a different module, e.g. Serialization is implemented inside the java.base module.
Further, in cases where the garbage collection of objects would be observable, e.g. for classes with nontrivial finalize() methods or weak references pointing to the objects, additional restrictions apply:
JLS §12.6.1., Implementing Finalization
Optimizing transformations of a program can be designed that reduce the number of objects that are reachable to be less than those which would naively be considered reachable. For example, a Java compiler or code generator may choose to set a variable or parameter that will no longer be used to null to cause the storage for such an object to be potentially reclaimable sooner.
Another example of this occurs if the values in an object’s fields are stored in registers. The program may then access the registers instead of the object, and never access the object again. This would imply that the object is garbage. Note that this sort of optimization is only allowed if references are on the stack, not stored in the heap.
This section also gives an example where such optimization would be forbidden:
class Foo {
private final Object finalizerGuardian = new Object() {
protected void finalize() throws Throwable {
/* finalize outer Foo object */
}
}
}
The specification emphasizes that even being otherwise entirely unused, the inner object must not get finalized before the outer object became unreachable.
This wouldn’t apply to long[] arrays which can’t have a finalizer, but it makes more checks necessary while reducing the versatility of such hypothetical optimization.
Since typical execution environments for Java allow to add new code dynamically, it is impossible to prove that such an optimization will stay unobservable. So the answer is, there is no such optimization that would eliminate an unused field from a class in practice.
There is, however, a special case. The JVM may optimize a particular use case of the class when the object’s entire lifetime is covered by the code the optimizer is looking at. This is checked by Escape Analysis.
When the preconditions are met, Scalar Replacement may be performed which will eliminate the heap allocation and turn the fields into the equivalent of local variables. Once your object has been decomposed into the three variables A, B, and C they are subject to the same optimizations as local variables. So they may end up in CPU registers instead of RAM or get eliminated entirely if they are never read or contain a predictable value.
Not that in this case, you don’t have to worry about the inheritance relation. Since this optimization only applies for a code path spanning the object’s entire lifetime, it includes its allocation, hence, its exact type is known. And all methods operating on the object must have been inlined already.
Since by this point, the outer object doesn’t exist anymore, eliminating the unused inner object also wouldn’t contradict the specification cited above.
So there’s no optimization removing an unused field in general, but for a particular Foo or Bar instance, it may happen. For those cases, even the existence of methods potentially using the field wouldn’t impose a problem, as the optimizer knows at this point, whether they are actually invoked during the object’s lifetime.
I came across the following code in an article somewhere on the Internet:
public class MyInt {
private int x;
public MyInt(int y) {
this.x = y;
}
public int getValue() {
return this.x;
}
}
The article states that
Constructors are not treated special by the compiler (JIT, CPU etc) so it is allowed to reorder instructions from the constructor and instructions that come after the constructor.
Also, this JSR-133 article about the Java Memory Model states that
A thread that can only see a reference to an object after that object has been completely initialized is guaranteed to see the correctly initialized values for that object’s final fields.
The abovementioned MyInt instance seems immutable (except that the class is not marked final) and thread-safe, but the articles state it is not. They state that it's not guaranteed that x always has the correct value upon read.
But I thought that
only the thread that creates an object should have access to it while it is being constructed
and the Java Tutorials seem so support that.
My question is: does it mean that, with the current JMM, a thread can have access to a partially constructed object due to instruction reordering? And if yes, how? And does that mean that the statement from the Java Tutorials is simply not true?
That article is saying that if you have code like
foo = new MyInt(7);
in a class that has a field
MyInt foo;
then the instructions that amount to
(reference to new object).x = 7;
foo = (reference to new object);
could be swapped over as some kind of optimisation. This will never change the behaviour of the thread that's running this code, but it's possible that some other thread will be able to read foo after the line
foo = (reference to new object);
but before the line
(reference to new object).x = 7;
in which case it would see foo.x as 0, not 7. That is to say, that other thread could run
int bar = someObject.getFoo().getValue();
and end up with bar equal to 0.
I've never seen anything like this happen in the wild, but the author seems to know what he's talking about.
Instruction reordering alone can not lead to another thread seeing a partially constructed object. By definition, the JVM is only allowed to reorder things if they don't affect a correctly synchronized program's behaviour.
It's unsafe publishing of the object reference that enables bad things to happen. Here's a particularly poor attempt at a singleton for example:
public class BadSingleton {
public static BadSingleton theInstance;
private int foo;
public BadSingleton() {
this.foo = 42;
if (theInstance == null) {
theInstance = this;
}
}
}
Here you accidentally publish the reference to the object being constructed in a static field. This would not necessarily be a problem until the JVM decides to reorder things and places this.foo = 42 after the assignment to theInstance. So the two things together conspire to break your invariants and allow another thread to see a BadSingleton.theInstance with its foo field uninitialised.
Another frequent source of accidental publication is calling overrideable methods from the constructor. This does not always lead to accidental publication, but the potential is there, hence it should be avoided.
only the thread that creates an object should have access to it while it is being constructed
And does that mean that the statement from the Java Tutorials is
simply not true?
Yes and no. It depends on how we interpret the word should. There is no guarantee that in every possible case another thread won't see a partially constructed object. But it's true in the sense that you should write code that doesn't allow it to happen.
Is there any difference in efficiency (e.g. execution time, code size, etc.) between these two ways of doing things?
Below are contrived examples that create objects and do nothing, but my actual scenarios may be creating new Threads, Listeners, etc. Assume the following pieces of code happen in a loop so that it might make a difference.
Using anonymous objects:
void doSomething() {
for (/* Assume some loop */) {
final Object obj1, obj2; // some free variables
IWorker anonymousWorker = new IWorker() {
doWork() {
// do things that refer to obj1 and obj2
}
};
}
}
Defining a class first:
void doSomething() {
for (/* Assume some loop */) {
Object obj1, obj2;
IWorker worker = new Worker(obj1, obj2);
}
}
static class Worker implements IWorker {
private Object obj1, obj2;
public CustomObject(Object obj1, Object obj2) {/* blah blah */}
#Override
public void doWork() {}
};
The only practical difference between the anonymous classes and the top-level classes is that the anonymous classes will hold an implicit reference to the outer class.
This won't manifest itself in performance, but will impact you if you ever serialise these classes.
There should be little if any performance difference. If there is a difference it will be at a level where it is not worth worrying about.
IMO, you should focus on writing code that is readable and maintainable, and ignore "micro" performance issues until you have clear evidence that they are significant ... based on profiling the application.
(For the record, when an anonymous inner class refers to a final in an enclosing scope, this is implemented at the bytecode level by means of hidden constructor arguments and hidden instance attributes. The bytecodes will be almost the same as the bytecodes that you get from your other implementation.)
It's important to realize that anonymous classes are still classes that were known and fully-compiled at compile time. The fact that, say, you're defining an anonymous class body, perhaps with many methods and fields etc within a loop, doesn't mean that the runtime has to compile that type on every iteration.
Thus, any difference in performance between the two approaches are negligible. The important factors to consider are things like readability, reusability, testability, etc.
I actually HAVE noticed a significance performance hit when instantiating many instances of an anonymous class.
Thinking if might be due to the local class being static I removed that and it made no difference.
In my case, I was doing something 1000 choose 3 times which is 499,500. The version with the local class (regardless of static or not) took 26 seconds and the version with the anonymous functionally identical class took 2 minutes 20 seconds.
Regarding performance you should consider if an inner class should be created or not at all.
An example for bad practice is something like:
public List<String> someMethod() {
return new ArrayList<String>() {{
add("Item one");
add("Item two");
}};
}
While this syntactical convenience looks smart at a first glance, this (often unnoticed) creates an anonymous inner class whose object keeps a reference to the outer instance.
As this object is also given to the outside as result value of someMethod, you cannot be sure what your caller does with this list.
If he puts the resulting ArrayList instance into some static variable, your current Object will be kept forever too!
Speculating about code performance is an excellent way of wasting your time. Nothing compares to actually benchmarking the code. If you're worried about performance, measure the code. If you suspect that your code is sub-optimal, profile the code to figure out where the time is spent, then try to improve those parts. At this time it may be appropriate to actually study the byte code to see if that may give you a hint which implementation is more efficient.
When you've done that, measure the code again to make sure that you didn't make things worse, for example by making the code uglier and more difficult to maintain.
I want to know what the modern C++11 equivalent of Java's instanceof. I have seen this SO post but it is quite old and was wondering if there's a more modern, better solution in C++11?
I was hoping there's a possibility of using a switch construct without having to resort to a manual enum class.
class A {
};
class B : public A {
}
class C : public A {
}
on_event(A& obj)
{
switch (obj) {
case A:
case B:
case C:
}
}
My base class does not have any virtual methods or functions. I am representing an expression tree for a parser and the base class is just a polymorphic holder - like an ADT in Haskell/OCaml.
The same answer still applies, and has always been like this in C++:
if (C * p = dynamic_cast<C *>(&obj))
{
// The type of obj is or is derived from C
}
else
{
// obj is not a C
}
This construction requires A to be polymorphic, i.e. to have virtual member functions.
Also note that this behaviour is different from comparing typeid(obj) == typeid(C), since the latter tests for exact type identity, whereas the dynamic cast, as well as Java's instanceof, only test for the target type to be a base class of the type of the most-derived object.
In C++ plain old data (POD) has no runtime type information. The classes described all take exactly 1 byte, and have identical runtime representations in any compiler with the empty base class optimization.
As such what you want cannot be done.
Adding a virtual destructor to the base class adds in RTTI, and dynamic_cast support.
Adding an enum or int field to the base that gets initialized differently for each derived class also works.
Yet another option is to create a template function, and store a pointer to it, like so:
using my_type_id=void(*)();
template<class>void get_my_type_id_helper(){};
template<class T> my_type_id get_my_type_id(){return get_my_type_id_helper<T>;}
and then storing a my_type_id in A initialized appropriately. This is reinventing RTTI, and as you want more features you will approach C++ RTTI overhead.
In C++ you only pay for what you ask for: you can ask for classes without RTTI, which you did, and get it.
RTTI is Run Time Type Information. POD is plain old data, a C++03 term. Many classes are not POD: the easy way is to add a virtual destructor. C++11 has more fine grained standard layout and aggregate terms.
Technically RTTI and POD are not opposites of each other: there are classes with no RTTI that are not POD.
Note that MSVC has options to not generate RTTI and its aggressive Comdat folding can break the manual RTTI I did above, in both cases in violation of the standard.
Maybe you are interested in the answer I've posted inside your mentioned old SO post.
https://stackoverflow.com/a/49296405/1266588
The answer presents an implementation of instanceof without the usage of dynamic_cast based on C++11, template metaprogramming and RTTI. A small performance measurement application demonstrates that it is more efficient than dynamic_cast if you use compiler optimization.
Don't do that. In most cases you should review your design when you ask for instanceof or dynamic_cast.
Why? You are most likely violating Liskov's substitiontin principle.
How about this approach:
class A {
public:
virtual void action();
virtual ~A();
};
class B : public A {
public: void action() override;
};
class C : public A {
public: void action() override;
};
void on_event(A& obj)
{
obj.action();
}
Note that as #Yakk pointed out you need at least one virtual method anyway to get dynamic polymorphism. And there is a rule that says: When you have at least one virtual method, always also write a virtual destructor in the base class.
You can do all this with templates and specialization or type tagging but I take from your question -- coming from Java -- you don't want to go there yet. You really like virtual methods, don't you? Sorry, that you have to mark them in C++.
If you're willing to limit yourself to types known at compile-time (rather than working through pointers on instances of classes with vtables) - then C++11 and later does have an instanceof equivalent: It is std::is_base_of.
You might also want to check out std::is_convertible and std::is_same.
It looks like anonymous class provides the basic functionality of closure, is that true?
There is almost no difference. In fact the there is an old saying about closures and objects. Closures are the poor man's object, and objects are the poor man's closure. Both are equally powerful in terms of what they can do. We are only arguing over expressiveness.
In Java we are modeling closures with Anonymous Objects. In fact a little history here is that originally Java had the ability to modify the outward scope without the use of final. This works and worked fine for Objects allocated in the local method scope, but when it comes to primitives this caused lots of controversy. Primitives are allocated on the stack so in order for them to live past the execution of the outer method Java would have to allocate memory on the heap and move those members into the heap. At that time people were very new to garbage collection and they didn't trust it so the claim was Java shouldn't allocate memory without explicit instruction from the programmer. In efforts to strike a compromise Java decided to use the final keyword.
http://madbean.com/2003/mb2003-49/
Now the interesting thing is that Java could remove that restriction and make use of the final keyword optional now that everyone is more comfortable with the garbage collector and it could be completely compatible from a language perspective. Although the work around for this issue is simple to define instance variables on your Anonymous Object and you can modify those as much as you wish. In fact that could be an easy way to implement closure style references to local scope by adding public instance variables to the anonymous class through the compiler, and rewriting the source code to use those instead of stack variables.
public Object someFunction() {
int someValue = 0;
SomeAnonymousClass implementation = new SomeAnonymousClass() {
public boolean callback() {
someValue++;
}
}
implementation.callback();
return someValue;
}
Would be rewritten to:
public Object someFunction() {
SomeAnonymousClass implementation = new SomeAnonymousClass() {
public int someValue = 0;
public boolean callback() {
someValue++;
}
}
implementation.callback();
// all references to someValue could be rewritten to
// use this instance variable instead.
return implementation.someValue;
}
I think the reason people complain about Anonymous inner classes has more to do with static typing vs dynamic typing. In Java we have to define an agreed upon interface for the implementor of the anonymous class and the code accepting the anonymous class. We have to do that so we can type check everything at compile time. If we had 1st class functions then Java would need to define a syntax for declaring a method's parameters and return types as a data type to remain a statically typed language for type safety. This would almost be as complex as defining an interface. (An interface can define multiple methods, a syntax for declaring 1st class methods would only be for one method). You could think of this as a short form interface syntax. Under the hood the compiler could translate the short form notation to an interface at compile time.
There are a lot of things that could be done to Java to improve the Anonymous Class experience without ditching the language or major surgery.
As far as they both affect otherwise "private" scoping, in a very limited sense, yes. however, there are so many differences that the answer might as well be no.
Since Java lacks the ability to handle blocks of code as true R-values, inner classes cannot pass blocks of code as is typically done in continuations. Therefore the closure as a continuation technique is completely missing.
While the lifetime of a class to be garbage collected is extended by people holding inner classes (similar to closures keeping variables alive while being rebound to the closure), the ability of Java to do renaming via binding is limited to comply with the existing Java syntax.
And to allow threads to properly not stomp over each other's data using Java's thread contention model, inner classes are further restricted with access to data that is guaranteed not to upset, aka final locals.
This completely ignores the other inner classes (aka static inner classes) which is slightly different in feel. In other words, it touches upon a few items that closures could handle, but falls short of the minimum requirements that most people would consider necessary to be called a closure.
IMHO, They serve a similar purpose, however a closure is intended to be more concise and potentially provide more functionality.
Say you want to use a local variable using an anonymous class.
final int[] i = { 0 };
final double[] d = { 0.0 };
Runnable run = new Runnable() {
public void run() {
d[0] = i[0] * 1.5;
}
};
executor.submit(run);
Closures avoid the need for most of the boiler plate coding by allowing you write just what is intended.
int i = 0;
double d = 0.0;
Runnable run = { => d = i * 1.5; };
executor.submit(run);
or even
executor.submit({ => d = i * 1.5; });
or if closures support code blocks.
executor.submit() {
d = i * 1.5;
}