This question already has answers here:
xor operation between java references
(4 answers)
Closed 6 years ago.
As Java doesn't provide a way to get the address of the object, is it feasible to code an XOR linked list?
If yes, can someone please elaborate, how to do that?
I don't believe you can (at least, not using object references for your "next" and "prev" pointers), for the reason you cite: Object addresses are officially opaque. Although we could access the bits of a reference, the JVM can move objects in memory (e.g., when doing memory management), and although I'm not immediately finding a spec citation for it, I believe it's allowed to handle that by modifying the object reference values (literally going and updating every field and such where the old reference is, giving it the new reference). So if we converted the object reference to a long (for instance) and then XOR'd that with another object reference converted to a long, if either object moved (as they can do), once either of those is XOR'd back and converted back into an object reference, it may well no longer be valid.
Consequently, I think you'd need to use something other than object references for the pointers, such as indexes into a big array of object references, at which point I'm fairly sure you've lost the memory benefit of the XOR linked list.
You can never do this in Java.
Even if you use sun.misc.Unsafe to get access to the real addresses of the objects, and even if you use a garbage collector that won't move objects around (Concurrent Mark Sweep doesn't move objects, I believe, as it's "non-compacting"), you have a bigger problem: By mangling the prev and next object references together in an integer, the garbage collector won't realize that they are object references. So it will think the referred objects are unreferenced, and consequently, will collect all your list nodes as garbage.
If you need to save memory, use an array-based list instead of a linked list.
Related
This question already has answers here:
Do arrays in Java store data or pointers
(3 answers)
Closed 4 years ago.
Basic question
Consider this object:
Person alice = new Person("Alice", 0);
It's added to two ArrayLists:
ArrayList<Person> foo = new ArrayList<Person>();
ArrayList<Person> bar = new ArrayList<Person>();
foo.add(alice);
bar.add(alice);
At this point, are there three Person objects in heap memory (alice plus one in each ArrayList)? Or is there one Person object in memory along with three references (pointers) to it?
Motivation for/more involved question
A Person object has two fields, a String and an int. Say I have many Person objects, and I want to have them all sorted in two different ways at different times (sometimes by their Strings alphabetically, sometimes by their ints numerically).
It seems this can be done in two ways:
Have one container, like an ArrayList, of the objects and sort it on demand whenever I want to change the sorting scheme
Have two containers, one which sorts Persons by their Strings alphabetically and one which sorts by their ints numerically
The first way is time inefficient but space efficient.
The second way is time efficient but space inefficient (say Person objects are very large).
In languages like C++, doing this efficiently in time and space would entail the second way but with multiple containers of pointers to a single collection of Person objects. Because this is difficult, people often recommend things like Boost's multi_index_container, which does exactly this. In Java, I've seen people elide this complexity, something that seems possible because all Java objects are behind pointer-like references at all times.
Are they correct in doing so? In Java, is doing things the second way in a space-efficient manner as simple as having multiple containers with redundant references to the same objects?
Bonus question
Is this true or untrue in other languages, like JavaScript, Python, Ruby, C#, Go, Rust, etc.?
At this point, are there three Person objects in heap memory (alice plus one in each ArrayList)?
One Person object in memory, with three object references (pointers). The Person alice variable you declared holds one reference, while each List you created holds a single element for an object reference (pointer). So a total of 3 references.
Technically speaking, a ArrayList is a list of object references (pointers), not objects. When we say ArrayList<Person>, we mean a list of pointers that are only allowed to point to objects of class Person but not School or Invoice. So the size of the Person object, School or Invoice object is irrelevant in terms of size in the List. Every List has elements containing only an object reference in each element, so they are always the same size.
The tricky part to understand is that Java syntax was purposely designed to hide the reference/pointer from us as Java programmers. This gives us the convenience in our day-to-day programming work of thinking of the List as containing Person objects. We know the underlying structure as actually references/pointers, but we need not think about that.
When we retrieve a Person from the List:
Person p = foo.get( 0 ) ; // Annoying zero-based index counting. So zero is the first element.
…Java does the work of accessing the element in the list, obtaining its stored reference/pointer, then following that reference/pointer to look up that object’s place in memory, and return that memory location (basically, a number) to be stored in the reference-to-a-Person-object variable named p here in this example.
When we get the name member from that Person object:
String name = p.name ;
…the JVM follows that reference/pointer stored in p to locate the actual object floating around elsewhere in memory, then moving through that chunk of memory to find the name member variable within the object.
In contrast, the C language makes these pointers quite obvious and available. This makes programming much more confusing and complicated, and much more error-prone.
You need not understand all this when starting out programming. Occassionally revisit the topic, mull it over, and eventually it will click to make sense. Diagrams can help. For more info and drawings, see a couple of my Answers to related Questions, here and here. Search Stack Overflow, as this topic has been covered many times such as here and here.
Sorting
Using the Java Collections Framework, you have two options to access a group of objects in sorted order: Either re-sort when switching order, or maintain two collections. The size of the content within the objects is irrelevant as only pointers are involved in the collections.
Of course third-parties are free to develop their own collections to exhibit other behavior.
We're using a recursion that iterates through tree nodes and does some computation that is a logical equivalent of something as
public static Result iterate(TreeNode node, Dictionary dictionary ) {
Map<String, Result> accumulated = new HashMap<String, Result>();
for (TreeNode child : node.getChildren()) {
Result partialResult = iterate(child, dictionary);
accumulated.put(child.getId(), partialResult);
}
return completeResult(accumulated);
}
Now the Dicitionary object is not mutated while the recursion is being done. Its simply used as a lookup table. The object is in fact quite big.
Does the fact that we have the dictionary as an argument of our recursive call have a negative impact on the memory/performance? Is this a bad design?
The really interesting issue is: "How is the Dictionary related to the Tree?"
If several Dictionaries need to be used with different iterations, you would indeed pass a Dictionary as a parameter to the iterate method, as you have it right now. (But why it "iterate" static?)
If a Dictionary is a stable property associated with some specific Tree object, its reference should be passed to the constructor and stored as an instance field. The iterate being a method could access it as any other instance field.
Possibly the Dictionary is universal and unique for all Tree objects? Then you might advocate setting the Dictionary as a static class field, and your iterate method would access it as a "global".
Technically, all of the above just passes a reference ("address") around; no copying of a potentially huge object is involved...
I would say your design is correct, in that it should produce correct results. For its performance, you would really need to do some thorough testing to assess, with various combinations of sizes for your tree structure and dictionary. Also, the implementation of Dictionary will probably play a major role in the performance characteristics.
Memory-wise, your current implementation should be the most economical, as you use the existing structures, instead of copying to others, in order to use a faster algorithm.
Passing the dictionary as an argument has the benefit of isolating each recursive run, in the case that the dictionary can change between runs, and provided that you copy the dictionary for each run. Also, it gives you the capability of using the same code to do concurrent searches (using threads) on different trees using different dictionaries. Using a global dictionary wouldn't allow you to do this.
I think this question boils down to whether Java passes by reference or value. Somewhat confusingly Java always passes by value, but where an object is passed the value is the object reference.
So for your example the method iterate takes a parameter Dictionary dictionary. The internals of this object will be stored on the heap. This is an area of memory that is shared among all objects. Additionally your method will have it's own unique reference on the stack. The reference acts as a kind of pointer so your method can lookup the values of dictionary.
When you make the recursive call the JVM will make a new reference to the same dictionary object and put this reference on the stack for the new method call. So now you have two calls to iterate on the call stack, both with their own individual reference to the dictionary object, but only one actual dictionary object on the heap.
If you were to make changes to the dictionary object using either reference it would update the same underlying object so both methods would see these changes.
When the method returns, since the dictionary reference is local to the method it will be removed from the stack. This will reduce the reference count to this object by 1. If the total number of references reaches 0 then your object becomes eligible for garbage collection since nothing will be able to see it.
Back to your question about memory I don't think you need to worry. It's the object on the heap where all of the data will be. References are cheap by comparison (8 bytes for a Java reference). Each reference will in theory take up a little memory but you are only likely to hit problems if your recursive loop doesn't exit.
This question already has answers here:
What's the advantage of a String being Immutable?
(7 answers)
Closed 9 years ago.
I have read a lot of places where it is written that immutability in java is a desired feature. Why is this so?
Immutability makes it easier to reason about the life cycle of the object. It is especially useful in multi-threaded programs as it makes it simpler to share between threads.
Some data structures assume the keys or elements are immutable, or are not changed in critical ways. e.g. Maps and Sets. They don't have to be strictly immutable but it makes it a lot easier if they are.
The downside of immutable objects is that it make recycling them much harder and can significantly impact performance.
In short, if performance is an issue, consider mutable objects, if not use immutable objects as much as possible.
The main benefit of immutability is that an object cannot be changed "out from under you". Eg, consider a String that is a key to a Map. If it were mutable then one could insert a key/value pair then modify the String that is the key. This would break the hash scheme used in the map, and lead to some potentially very unpredictable operation.
In some cases such mutability could lead to security exposures, due to intentional abuse, but more commonly it would simply lead to mysterious bugs. And "defensive" copying of the mutable objects (to avoid such bugs) would lead to many more objects being created (especially if a formulaic approach to the problem is taken).
(On the other hand, lots of objects are created, eg, because a new String is created when someone appends to the String, or "chops off" a part of it, vs simply mutating the existing String, so both approaches end up causing more objects to be created, for different reasons.)
Immutability is highly desired when you need to know that a class hasn't changed when you don't expect. Consider the keys in a hash map. If you set a mutable object for a key, then store it at the key's current hash value (mod hash array size), what happens when you change it? The hash changes and suddenly it's in the wrong spot! You (the HashMap) don't know that it has changed, so you don't know to update its location, so the next time someone tries to look up that key, you won't find it. Immutability removes this problem - if you put an object somewhere based on its hash, you know it will always be where you expect it to be.
And, as pointed out elsewhere, being immutable means it's safe to read concurrently from multiple threads without synchronization.
In programming, an immutable class or object is an object whose state can not be modified after it is created. Some cases they are still considered as immutable even if you can change their attributes (fields), but the object nature keeps same.
Immutable Objects are often desired because 3 main reasons:
Thread-safe
Higher security than mutable objects
Simplicity
There is a ref. that you can review for a better understanding about immutability for java classes and objects
Effective Java Item 15 Immutable classes are easier to design, implement, and use than mutable classes. They are less prone
to error and are more secure.
When an array of objects is not referenced anymore, does the objects in that array are garbage collected too? (assuming no variables are referencing the elements)
In this page, http://java.sys-con.com/node/37613
it says -
"The biggest danger is placing an object into a collection and forgetting to remove it. The memory used by that object will never be reclaimed."
If you make sure to nullify the references, why will that memory be unclaimed?
Thanks
When an array of objects is not referenced anymore, does the objects
in that array are garbage collected too? (assuming no variables are
referencing the elements)
Yes.
"The biggest danger is placing an object into a collection and
forgetting to remove it. The memory used by that object will never be
reclaimed."
This is when you are holding a reference to the collection. For example, if you have a Map in which you put a key-value and then forget to remove then it stays there for ever. Think http sessions, if you use something in ServerContext or some such at start of request using session id as key but fail to remove it at end of the request processing..
For the first question, the answer is yes, absolutely: the objects inside non-referenced array and no other references do get garbage collected.
As for the second question, the document talks about placing forgetting an object inside a referenced collection, for example a cache of some sort, a static field, a thread-local store, etc.
It won't be unclaimed if nothing references it. The article says that if you nullify a reference, but the object is still in a referenced collection (hence referenced), it won't be collected.
Generally speaking, anything that's not referenced is garbage collected. So, yes, those objects would be garbage collected.
Also, note that:
An array is not a collection.
I think that what the person that wrote that meant was make sure you
remember all of the places you're referencing an object, so that if
you intend to remove it, it gets removed (and there are no lingering
references to it).
This question already has answers here:
Does Java have pointers?
(12 answers)
Closed 9 years ago.
Why we are not using the pointer here?
Which concept is used instead of pointer in Java?
Why can't we use pointers in Java?
Because the language designers chose not to include pointers in the language.
Why we are not using the pointer here.
Because the designers of Java thought it was a tricky-to-use and error prone construct.
Which concept is used instead of pointer in Java?
References (which are quite similar to pointers if you disregard from pointer arithmetic).
Keep in mind that all objects you create, you create on the heap (using the new keyword). This fact, together with the fact that there is no "dereference operator" (* in C/C++) means that there's no way to get hold of an object! Since you can't get hold of an object, there's no way you can store an object in a variable. Therefor all variables (except the ones holding primitive types) are of reference-type.
It was a language design decision.
From the sun white paper The Java Language Environment:
Most studies agree that pointers are one of the primary features that
enable programmers to inject bugs into their code. Given that
structures are gone, and arrays and strings are objects, the need for
pointers to these constructs goes away. Thus, Java has no pointer data
types. Any task that would require arrays, structures, and pointers in
C can be more easily and reliably performed by declaring objects and
arrays of objects. Instead of complex pointer manipulation on array
pointers, you access arrays by their arithmetic indices. The Java
run-time system checks all array indexing to ensure indices are within
the bounds of the array.
You no longer have dangling pointers and trashing of memory because of
incorrect pointers, because there are no pointers in Java.
It's good isn't it? You don't have pointers in the C programming sense, the Virtual Machine looks after all that. However, that's not to say you don'f have have similar capabilities. For example, variables for objects are references, when you pass a variable for an object you are passing a reference which is sort of a pointer. You might also use a variable to store the index of an item in an array, that again is a kind of pointer in a programmatical sense.
Everything in Java is accessed only through pointers. Java references are pointers. The creator of java Dr.Gosling says this in his book, "The Java Language Specification" (somewhere around p.40 in one edition).
In fact another book "The Java Virtual Machine" says: "A reference is a pointer to a pair of pointers; one of theses two pointers points to another pointer [...]".
There are marked differences between Java references and C pointers but nevertheless references are pointers.
In Java any reference to a simple type is always by value and any reference
to an object is always a pointer except in cases of special objects.
every object you create using new(); is actually pointer..
XXX a=new XXX();
a is actually a pointer..
It's just you cannot do fancy thing like pointer arithmetic to them like you can in C (for safety reasons).
so actually if you are passing an object, you are passing the pointer to the object (object created by new() resides in heap).
You can access pointer mechanics using java.misc.unsafe, but that's... mmm... unsafe.
Ah, about replacing concept. What aspect are you interested in? Variables are already represented by references to them - that's one point of view. If you need pointers to implement efficient data structures, you, most probably already have one, or there is a library providing that feature, or you can write some native code and call it from java wrapper. Anyway, please define aspects you are interested in and maybe community will give you more detailed answer.
Java follows the principle of call by value. So if you create an object, you will get back a copy of a reference to the created object in the heap space. This copy of a reference is what a variable gets assigned to. If you then use this variable as an argument for a method call, again a copy of that reference is created and used instead. Java never uses references or pointers! Everything in java is a copy. Hence Java follows the call by value principle.
The most difficult thing to manipulate in any programming language is with pointers.
If u just miss something you get lots of errors namely segmentation faults.
Java is one such language providing users the flexibility to do things using CALL BY VALUE .
If you want to change the value of a variable in a C function you pass the address (pointer) of the variable to the function. If you want to use the value of a variable in a function and do not wish to change its value, you pass the name (reference) of the variable to the function. Many programmers never used pointers for any thing else, like linked lists and b trees. C pointers and structures can make some applications infinitely easier. Structures unlike arrays can contain different types of variables and grouping them together makes life easier. Structures in a linked lists contain pointers (addresses to the next link in the list and also to the previous link if the list is double linked. This can make sorting a breeze.
A link in the list can also contain pointers to different structures which allow you to associate the linked lists of different materials or conditions with each link in the first list.
Since the memory is allocated where and as needed rather than being dimensioned as in an array, it gives you tremendous flexibility.The main application I have used this for is calculating the cost of projects to bid jobs.
This flexibility demands close attention to details and no holds barred debugging.