Consider this class:
public class Test {
private int bar = 5;
public void foo () {
System.out.println("hi");
}
}
Now imagine we have the following section of code executing:
Test obj1 = new Test();
Test obj2 = new Test();
Test obj3 = new Test();
All three objects exist in the same scope. Because bar is not static, there will be three separate instances of bar in memory.
Are there three instances of the method foo in memory?
Does the JVM do some magic so that each object can use one method declaration in memory?
Is there a name for this situation so that I can see if other languages do it?
Methods are referenced by indices, there are no instances of methods, i.e. they don't take up additional memory.
The Java instruction set responsible for handling a method based on a class is invokevirtual:
http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.invokevirtual
Here is a more detailed look of what happens under the hood (explained far better then I could):
http://zeroturnaround.com/rebellabs/java-bytecode-fundamentals-using-objects-and-calling-methods/
Other references
How the hava virtual machine handles method invocation and return
Here is a similar SO question:
How much memory is used for function references in a Java object?
Are there three instances of the method foo in memory?
No.
Does the JVM do some magic so that each object can use one method declaration in memory?
No.
Is there a name for this situation so that I can see if other languages do it?
What makes you think there are any other languages that do it? The real question here is why do you think methods would be instantiated per instance? What would be the point?
To be clearer, there is absolutely no need for different objects to have different code for their methods. Assuming you have 3 instances of Test, you need three versions of the 'bar' member because they can have different values. However all of the three 'foo' methods do exactly the same thing. The bits that represent the code are absolutely identical. Having three (identical) versions would be completely pointless.
All other computer languages do this too. In fact you will find that on a computer, if you execute (say) a text editor on three documents at once, there will be three areas of data representing the three documents, but only one place in memory where the actual code of the application is stored. The three 'instances' share it.
Related
I would like to share an object between various instances of objects of the same class.
Conceptually, while my program is running, all the objects of class A access the same object of class B.
I've seen that static is system-wide and that its usage is discouraged. Does that mean that if I've got another program running on the same JVM that instantiates objects of class A, these objects could potentially access the same B object as the one accessed in the previous program?
What are generally the flaws behind using static fields?
Are there any alternatives (that do not require a huge effort of implementation)?
Static doesn't quite mean "shared by all instances" - it means "not related to a particular instance at all". In other words, you could get at the static field in class A without ever creating any instances.
As for running two programs within the same JVM - it really depends on exactly what you mean by "running two programs". The static field is effectively associated with the class object, which is in turn associated with a classloader. So if these two programs use separate classloader instances, you'll have two independent static variables. If they both use the same classloader, then there'll only be one so they'll see each other's changes.
As for an alternative - there are various options. One is to pass the reference to the "shared" object to the constructor of each object you create which needs it. It will then need to store that reference for later. This can be a bit of a pain and suck up a bit more memory than a static approach, but it does make for easy testability.
Static methods and members are discouraged because they're so frequently misused, but this sounds like a situation where static is the correct way to go. As to static shared across multiple programs, this is not the case. Each program runs in a completely separate environment.
What you are looking for is called the Singleton Pattern.
Assuming everything is in the same class loader, then why not use the monostate pattern to do this?
Your shared static is hidden in the monostate:
public class Monostate {
private static String str = "Default";
public String getString() {
return str;
}
public void setString(String s) {
str = s;
}
}
Then you are free to create as many instances of the monostate as you like, but they all share the same underlying object due to the static reference.
Monostate mono = new Monostate();
mono.setString("Fred");
System.out.println(mono.getString());
I would like to know that if I have the following class.
class Example {
public static void method1() {}
public void method2() {}
public void method3() {}
}
Only 1 method is static and it should be the first thing to be loaded in the memory during runtime. But what about the instance methods? Are they loaded in the memory when an instance of this class is created? Or are they already loaded when the class is loaded initially.
What I am trying to understand is if it is a better approach to have all the functionality in the same class by having separate methods for each functionality or is it better to create a separate class for each functionality with only there respective methods in its class.
So will it help memory wise in the later case because I will only create the instance of the class that I need to use and only that much of methods will be loaded in the memory. Otherwise, in the former case, where I have 100 methods in the same class, but I only need to use just 2 methods out of them, it will be waste of memory because all 100 methods are loaded.
Any suggestions?
Actually memory allocation for class variables and class member functions/methods are done differently. When a class is being instantiated its class variables are being created in the memory which is call as data segment and method codes are created in code segment. IF we create ten objects of a particular class java virtual machine will create ten different code segments but only one code segment will be created for all the object. Java virtual machine will create a code segment only when there is at least one reference to that that class object in the code else it will not.
Code segment captured minimal memory only. It just stores assembly instructions created from code. Hence you no need to worry about it. For object also a programmer no need to worry about managing the memory in Java as there is a garbage collector in java.
Now answer to your question in my comment section:-
But will the methods themselves be stored somewhere in heap etc. ? So a class having 100 methods or 2 methods will behave the same memory wise?
As I said your method's codes will be converted into assembly instruction by your java virtual machine and will be stored in the memory in an instruction pointer for each method. Not necessarily now many method, it will depends on lines of code, recursion, loops, and condition etc. Yes if 100 methods of same size of codes with all the above then it will takes more memory than two methods.
I reference the same method twice but the references are different. See this example:
import java.util.function.Consumer;
public class MethodRefTest {
public static void main(String[] args) {
new MethodRefTest();
}
public MethodRefTest() {
Consumer<Integer> a = this::method;
System.out.println(a);
Consumer<Integer> b = this::method;
System.out.println(b);
}
public void method(Integer value) {
}
}
The output is:
MethodRefTest$$Lambda$1/250421012#4c873330
MethodRefTest$$Lambda$2/295530567#776ec8df
Are method references nothing more than syntactic sugar for anonymous classes? If not, what do I have to do to always get the same method reference? (Aside from storing a reference once in a field to work with.)
(Application: I thought of method references as a prettier way of observer implementation. But with different references each time it's impossible to remove an observer from an observable once it's added.)
Are method references nothing more than syntactic sugar for anonymous classes?
Correct. They aren't necessarily always implemented as heavyweight as that, but conceptually it's all they are.
If not, what do I have to do to always get the same method reference? (Aside from storing a reference once in a field to work with.)
Store the reference in a field. That's the answer. (Sorry.)
You ask,
Are method references nothing more than syntactic sugar for anonymous classes?
The JLS says that
Evaluation of a method reference expression produces an instance of a functional interface type
(JLS 8, section 15.13)
That doesn't explicitly require an anonymous class, but it does require some class, and it does not provide a mechanism for naming that class. I can imagine alternatives, but using the existing anonymous class mechanism seems pretty natural.
It is plausible that an implementation could recognize multiple references to the same method and use the same anonymous class for them, but such behavior is by no means required, and you have demonstrated that your implementation does not do it. Even if an implementation did do that, however, the JLS is at minimum suggestive that each evaluation of a method reference expression produces a new object.
You go on,
If not, what do I have to do to always get the same method reference? (Aside from storing a reference once in a field to work with.)
Your only guaranteed mechanism is to evaluate the method reference just once, and to then hold on to a reference to the resulting object as long as you have need of it. Storing the reference in a field, as #JohnKugelman describes, is one variation on that, but depending on the scope in which you need to refer to the same method reference object, it might suffice to store it in a local variable or to pass it around via method arguments.
Generally speaking the easiest and efficient way is storing the reference either in a field or a (local) variable.
First of all, the toString() output of the object generated for a method reference is entirely unspecified, hence, you cannot draw any conclusions about the object’s identity from there. Also, the hexadecimal number is an implementation dependent hashcode that is rarely an address. The only reliable way to check the identity of the object is to do a==b.
Still, these objects are indeed different, but that’s an implementation detail. As explained in Does a lambda expression create an object on the heap every time it's executed?, the JVM has a lot of freedom regarding object reuse, but the current HotSpot/OpenJDK implementation will reuse objects only for non-capturing expressions and this::method is capturing the this reference. Also, as shown by the code of your question, each occurrence of this::method in your code will even get its own generated class.
This is explained in Is method reference caching a good idea in Java 8?, which also concludes that you shouldn’t keep these instances for performance reasons. But in your case, when you want to deregister a listener reliably, keeping the reference in a variable is the only way to do it. As even for a single occurrence of a non-capturing expression, for which the current implementation will provide the same object, there is no guaranty that this will work, as this reuse still is an implementation dependent behavior.
This question already has answers here:
find out the differences between two java beans for version tracking
(4 answers)
Closed 6 years ago.
I have two instances of the same class. I need to find property(s) which are different amongst them (basically value of the property, say firstName might be different in both). The fields are primitive, complex as well as collections.
Basically, I need to find differences between two instances and if the fields are different in both the instances, I will copy value of the field from first instance to a third instance (diff object).
I think I can use reflection, but the classes are very complex and it might become error prone.
Your question is a bit unclear. First you said "two instances of the same class", then you said "the classes are very complex". Is this a generic solution to find differences between instances for any class, or is it just a specific case? The other ambiguity is what you mean by "copy the differences". For example, if its a String, then what is the difference between the two strings that would get copied into the new instance? If its a collection, what is the difference between the collections? What if you have two ArrayLists that have the same things in different orders.
If its a specific case, then you can just create a method on the class where you pass in an instance of the same class. Then you can iterate over each field and compare the differences.
public TheClass difference(TheClass that) {
TheClass newClass = new TheClas()
if (this.getName().equals(that.getName()) == false ) {
newClass.setName(that.getName());
}
...
}
But this can get out of hand depending on how deep your object graph is.
Perhaps the builder pattern might come in handy here if you're trying to build a generic/reusable solution. You might look at the Apache Commons code base and see how they implement HashCodeBuilder and ToStringBuilder. They even have a reflection version of the utilities. See how they handle deep and shallow equals.
There is no other way than to use reflection if you want to do it generically. If your fields have getters then you could keep comparing it with equals method. Then you have know the fields at compile time.
write a method like
public YourClass diff(YourClass other) {
// diff code here
}
or
public static YourClass diff(YourClass first, YourClass second) {
// diff code here
}
and wrap some unit tests around the implementations.
Reflection might seem more complicated, but it has the following advantages:
1) It can be generic and you can make the same code work with any class
2) It will not have to be changed if the class evolves.
If you want to go with reflection, you can use Class.getDeclaredFields() (google for "java class api 6") to get all the fields on the class, and then you can use the Field api to get the values for an object. If you wanted to be really fancy, you have a static String[] "diffIgnoredFields" and include field names you want to ignore in the diff.
You need to be careful. Some formulations of this problem are essentially the same as the Subgraph Isomorphism Problem which is known to be NP complete.
There's a piece of code that looks like this. The problem is that during bootup, 2 initialization takes place. (1) Some method does a reflection on ForumRepository & performs a newInstance() purely to invoke #setCacheEngine. (2) Another method following that invokes #start(). I am noticing that the hashCode of the #cache member variable is different sometimes in some weird scenarios. Since only 1 piece of code invokes #setCacheEngine, how can the hashCode change during runtime (I am assuming that a different instance will have a different hashCode). Is there a bug here somewhere ?
public class ForumRepository implements Cacheable
{
private static CacheEngine cache;
private static ForumRepository instance;
public void setCacheEngine(CacheEngine engine) { cache = engine; }
public synchronized static void start()
{
instance = new ForumRepository();
}
public synchronized static void addForum( ... )
{
cache.add( .. );
System.out.println( cache.hashCode() );
// snipped
}
public synchronized static void getForum( ... )
{
... cache.get( .. );
System.out.println( cache.hashCode() );
// snipped
}
}
The whole system is wired up & initialized in the init method of a servlet.
And the init() method looks like this conceptually:
// create an instance of the DefaultCacheEngine
cache = (CacheEngine)Class.forName( "com..DefaultCacheEngine" ).newInstance();
cache.init();
// init the ForumRepository's static member
Object o = Class.forName( "com.jforum....ForumRepository" ).newInstance();
if( o instanceof Cacheable )
((Cacheable)o).setCacheEngine(cache);
// Now start the ForumRepository
ForumRepository.start();
UPDATE I didn't write this code. It is taken from jforum
UPDATE 2 Solution found. I added a separate comment below describing the cause of the problem. Thanks to everyone.
You're going to have to give WAY more information than this, but CacheEngine is probably a mutable data type, and worse, it may even be shared by others. Depending on how CacheEngine defines its hashCode(), this could very well lead to aForumRepository seeing various different hash codes from its cache.
It's perfectly fine for the same object, if it's mutable, to change its hashCode() over a period of time, as long as it's done in a consistent manner (which is another topic altogether).
See also
Object.hashCode() -- make sure you understand the implications of the contract
On cache being static
More information has resurfaced, and we now know that the object in question, while mutable, does not #Override hashCode(). However, there seems to be a serious issue in design in making cache a static field of ForumRepository class, with a non-static "setter" setCacheEngine (which looks to be specified by Cacheable).
This means that there is only incarnation of cache, no matter how many ForumRepository instances are created! In a way, all instances of ForumRepository are "sharing" the same cache!
JLS 8.3.1.1 static Fields
If a field is declared static, there exists exactly one incarnation of the field, no matter how many instances (possibly zero) of the class may eventually be created. A static field, sometimes called a class variable, is incarnated when the class is initialized.
I think it's important to step back right now and ask these questions:
Does cache need to be static? Is this intended?
Should instances of ForumRepository have their own cache?
... or should they all "share" the same cache?
How many instances of ForumRepository will be created?
Putting pros and cons of the design pattern aside, should ForumRepository be a singleton?
How many times can setCacheEngine be called on a ForumRepository object?
Would it benefit from a defensive mechanism of throwing IllegalStateException if it's called more than once?
The best recommendations would depend on the answers to the above questions. The third bullet point is something that is immediately actionable, and would reveal if setCacheEngine is getting invoked multiple times. Even if they're only invoked once for each ForumRepository instance, it's still effectively a multiple "set" in the current state of affairss, since there's only one cache.
A static field with a non-static setter is a design decision that needs to be thoroughly reexamined.
are you sure the ForumRepository classes that you are comparing are the same. if you are doing newInstance you might have a weird classloader issue.
Mutable objects with hashCode implementations based on mutable state are almost always a bad idea. For example, they behave very strangely in hash-based collections -- if you insert such an object into a HashSet and then mutate it, the contains method won't be able to find it anymore.
Objects that are naturally distinguished by their identity should not override equals and hashCode at all. If you override hashCode based on state, that state should be immutable. Examples are String and the boxing types. Those are often referred to as "value classes", because their identity has no significance -- it is meaningless to distinguish between multiple instances of new Integer(42).
The thing that puzzles me about this question is this:
Why are you looking at the hashcode of a CacheEngine instance?
It seems that your code is putting Forum objects into a cache and getting them back. As such, it makes sense to look at the hashcode values for the Forum instances. But the hashcode of the cache itself would appear to be entirely irrelevant.
Having said that, if the DefaultCacheEngine class inherits its implementation of hashcode from java.lang.Object then the value returned by the method is the "identity" hashcode, and this cannot change over the lifetime of an object. If it does appear to change, this means that you are now looking at a different instance of the DefaultCacheEngine class.
I've solved my problem and I would like to share with you what I've learnt or discovered.
Root cause of the bug
The jforum.war webapp was being loaded twice by Tomcat 6.x, via two different virtual hosts. So yes, the CacheEngine was displaying two different hashCodes because they were loaded up in separate webapp classloaders.
Solution
The quick fix for me was to limit the invocation of the servlets in jforum.war via one specific virtual host address.