Memory allocation of Array [closed] - java

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
If I declare array of Strings like,
String []str = new String[3]; //line 1
It creates one reference(pointer) in stack for string array, but still I need to do str[0] = new String(); to initialize String in array.
I understand that line 1 just allocates memory to pointers that will be used to point to Strings in array.
My doubt is, are these references(pointers) allocated memory in heap(most probably yes, because new is used), if yes, than why?

When you declare an array of strings like, String[] str = new String[3];, you are not just creating a single reference to the array. Rather you are creating an array of references for each string. In the above example, an array of three references will be created. All these three references will be created in the stack itself. Note that in JAVA, all primitive types and references will be created in stack itself. After the above statement, all the three string references will be pointing to a special null object.
Now, when you start creating the actual string objects using str[0] = new String();, then the new string object itself will be created in the HEAP. And the first reference in the array of references points to the newly created string object.
Instead, if you just say new String(), with out any assignment on the left side, the new string object will be created in the HEAP, and there will not be any reference to it. That means, we can not access the newly created string object in subsequent steps.
Let us say, you again do something like str[0] = null;, then the reference again points back to null, and we will not have any reference to the string object that we created earlier. In other words, we can not access the string object any more.

Java has no pointers. But if you had used an Object with a default toString(), like an array!, you'd get something like a reference address
int[] test = new int[] {1};
int[] test2 = new int[] {1};
System.out.printf("%s %s%n", test, test2);
Which outputs (here but your's will have two different address, very probably, every time)
[I#15db9742 [I#6d06d69c

The reference to the array will be on the stack. The array will be on the heap. If you add new references to the array, then the references will be on the heap (as the array itself is on the heap). Provided there are no other references pointing to the same String.
PS : Since the introduction of Escape Analysis from Java6U23, the allocation could be done / moved to the stack itself.

Generally speaking, primitive objects (int, long, byte, etc) along with array references (String[], int[], etc) would be on the stack. Any complex objects (ex. String, ArrayList, Cat, Dog, Foo, Double, Long (notice the capitalised D and L in Double and Long vs the smaller ones) etc), would reside on the heap.

Related

String confusion in java [duplicate]

This question already has answers here:
Immutability of Strings in Java
(26 answers)
Closed 9 years ago.
From the oracle doc
String is immutable also Strings are constant; their values
cannot be changed after they are created. and because they are
immutable they can be shared. String buffers support mutable strings.
but I can always do the following:
String name="SO";
name="SE";
I can change the value so how can it be immutable and it is said that for security reason also like database connectivity etc..
Pardon me for asking such basic question but I need to understand.
name="SE" by doing this, you are changing the value of name variable, not the String object SO itself. String are immutable in the sense, String object SO can't be modified once created. By doing name = name+"TEST"; there will be a new String object SOTEST created in the memory, not existing String object SO will be modified.
For further details look here and here. There are lot of example and explanation.
Yes, you can change the string your name variable points to. But let's see what happens when you execute the following code sequence:
String name = "SO"; //line 1
name = "SE"; //line 2
At line 1: a new String object is created, that holds the value "SO";
At line 2: a new String object is created, that holds the value "SE"; your name variable value changes, in that it points to another reference, which is the second String object; the first String object ("SO") is still on the heap, but is not referenced anymore and is made available for future garbage collections, if any.
What you have to understand here is that, as soon as the String object containing the char sequence {'S', 'O'} is constructed, the char sequence wrapped by that String object could never change again. E.g. you cannot make that object wrap the char sequence {'S', 'E'}. That's what immutability is all about.
In the example you provide you have created two Strings. First a String SO is created and the reference is assigned to name. Then a new String is created, SE and that reference is assigned to name. You never actually modified the first String that was created.
String temp = "SO";
String name = temp;
name = "SE";
System.out.println(temp.equals("SO")); //prints true;
System.out.println(temp == name); //compares references prints false
When you change value of your String reference, you in fact create new object.And your reference now is linked to this new object.
String myValue = "old"; -> VM creates String object "old"
myValue = "new"; -> VM created String object "new"; "old" object still exists but any reference is linked to this, so we can say : "old" is lost
See for example the below image from the internet:
The big cloud is the heap where objects are being stored, s is the reference to the object (in your question you are using name as the reference)
When you do s = "abcd" a new object is created in the heap, and s is a reference to it. (Like the top arrow shows)
The important bit:
When you then do something like s = "abcdef" or s = s + "ef" the immutable string object "abcd" cannot be changed and so a new object is created and s loses it's reference to the old string (shown by dotted line) and now references the new String (Shown by the bottom arrow).
The old object I would assume is picked up by Garbage Collector at some point.

How know size of the object in java [duplicate]

This question already has answers here:
How to determine the size of an object in Java
(28 answers)
Closed 8 years ago.
It was an interview question that a List contains 5 objects like Organisation, Employee, Address,Country etc. How will you know which object is the heaviest one without running through java agent. There is one condition that all the objects available inside Arraylist are not serializable. Basically interviewer wants know how to write code know the size of the objects available inside ArrayList so that you can now that a particular object is heavier. Please provide me help. Once again let me put the conditions once again.
You can not use any profiler tool.
All the objects are not serializable.
You can run though java agent.
You have to write code to test and run as normal java program.
You can use instrumentation interface.
http://www.javapractices.com/topic/TopicAction.do?Id=83
You can't practically do this. Bear in mind that Java deals in references, and your list will simply contain a reference to the given object. Consider:
MyBigObject obj = new MyBigObject();
List<MyBigObject> list1 = new ArrayList<MyBigObject>();
list1.add(obj);
So your list contains a reference to your object. Now if I do this:
List<MyBigObject> list2 = new ArrayList<MyBigObject>();
list2.add(obj);
my second list contains a reference, to the same object. To say that list2 actually is the size of the 'contained' object is meaningless.
When you construct objects, they consist of primitives and references. You can account for the size of the primitives (since they're copied by value) but you can't do this for the references objects, since they're simply pointers to other objects. You can say an object is a certain size and made up of references (which may be 32 or 64 bit), but that's another matter.
You can see how much space is needed to allocate an object by doing -XX:-UseTLAB on the command line and use this method
public static long memoryUsed() {
return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
}
long before = memoryUsed();
new Object();
long used = memoryUsed() - before; // 16 bytes.
You can also use reflection to scan through the fields of each object. You can use Unsafe to get the offset of each of the fields and estimate the end of the object (including object alignment)

Best way to share Java variables between classes [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have an odd problem in Java. I can solve it but the solution seems inefficient.
I have a class, which simplified is
class Zot
{
double edges[];
}
The problem is that in many cases I want instance A and instance B to share ONE of the edge instances. In other words, instance A may allocate edge[2] and want instance B to share edge[2]. This is easy enough in that I can just set instance B to point at instance's A edge[2]. But how can I do it efficiently? If I allocate the edges[] in instance A, I can then simply assign B's instance to point to A. But often I only want to allocate a single edge (e.g. edge[2]) in A and then assign it in B. But in Java, one cannot (as far as I know) allocate a single member of an array (as one can in C++). Ideally, I only want to allocate the useful member and assign it. I could, of course, allocate all 4 members, assign the ones I need, then set the unwanted members to null and let GC clean it all up, but if there are hundreds or thousands of instances that seems clumsy.
Suggestions?
You can declare and allocate double edges[] outside of both classes, then pass this array as a parameter in the constructor into both of the instances that want to share it.
In Java an array is also an object. When you make an instance like double edges[] = new double[2]; edges will be passed around as a pointer, not as a copy.
This means if you make a change in the array in your class A, then class B will also see this change.
As I understand the question, you appear to want to share an individual element from your edges array between classes, and not share the whole array itself.
If your edges array was an array of Objects then this would be possible, and could make sense. However, since your array is a primitive array then there is no real concept of sharing an individual element.
You can assign an element of your array to equal the element of another array, but subsequent changes to the element in one array will not be reflected in the other array.
You can share the entire array between classes, in which case any changes will be reflected in both arrays (well, there is only one array, so both classes will see the changes to the single array that they both reference).
Most importantly:
When you declare an array of primitives in java, the memory is allocated immediately so there is no benefit (or mechanism) to declare only a single element of the array. So with your current data model, there is no reason for you to not predeclare your arrays since you cannot save space with them.

Object Creation JAVA [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the difference between “text” and new String(“text”) in Java?
Please explain the brief and detailed difference between following 2 statements:
String a= "somevalue";
String b = new String("somevalue");
I know that 2nd statement creates and provide memory to String Object b in heap. But why object a doesn't get memory and its still allowed to operate on string methods.
a and b are references to Objects, not Objects.
When you do a = b; it doesn't copy the Object, it copies a reference to an Object.
A String has a char[] inside it which is another object.
a gets an reference to an existing object so it may not need any extra memory.
b get a reference to a newly created object so that requires more memory.
its still allowed to operate on string methods.
This has nothing to do with how the object was created.
The first affects the literal String object "somvalue" to variable a. This literal String object is cached in a pool, as all literal Strings.
The second creates a new instance of empty String. Since String instances are immutable, it's equivalent to String b = "";, except it instantiates a new object for nothing.

Why does Java string have a copy constructor? [duplicate]

This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
What is the purpose of the expression “new String(…)” in Java?
It's immutable, why would you need to invoke String.String(String str) ?
From the API doc:
Unless an explicit copy of original is needed, use of this constructor is
unnecessary since Strings are immutable.
The only reason I can think of is in the situation where:
You've created a very large String: A.
You've created a small substring: B based on A. If you look at the implementation of substring you'll see it references the same char[] array as the original string.
String A has gone out of scope and you wish to reduce memory consumption.
Creating an explicit copy of B will mean that the copy: B' no longer references the large char[]. Allowing B to go out of scope will allow the garbage collector to reclaim the large char[] that backs A and B, leaving only the small char[] backing B'.
new String(s) can help garbase collection:
String huge = ...;
String small = s.substring(0,2); //huge.value char[] is not garbage collected here
String gcFriendly = new String(small); //now huge.value char[] can be garbage collected
Just in case you need String that are not the same but equal.
Maybe for testing to make sure, people really do str.equals(str2) instead of (str == str2). But I never needed it.

Categories