What does this statement mean in Java? - java

Suppose there is an array declaration:
int [] a = new int[3];
I'm reading a book that says the reason we need to explicitly create arrays at runtime is because we cannot know how much space to reserve for the array at compile time. So, in this case above don't we know we need to reserve 3 times the size of int of the underlying java platform ?

So, in this case above don't we know we need to reserve 3 times the size of int of the underlying java platform ?
Well actually slightly more than that - because arrays are objects with a class reference, as well as the length.
But yes, in this case you happen to know the size in advance. But Java also lets you write:
int[] a = new int[getLengthFromMethod()];
... in which case no, the amount of memory won't be known at compile time. This flexibility makes it considerably simpler to work with arrays than if you had to know the size at compile time. (Imagine trying to make ArrayList work otherwise, for example.)
But bear in mind that memory allocation is very dynamic in Java in general - it's effectively only really the size of stack frames which is known in advance, and then only in relative terms (as the size of a reference can vary between platforms). All1 objects are allocated on the heap and references are used to keep track of them.
1 Okay, aside from smart JVMs which are sometimes able to allocate inline after performing escape analysis.

In that book it probably says that there are scenarios in which you don't know at compile time how large an array will be (e.g.: when you ask a user for a set of numbers you don't know how many numbers he will insert).
In your example (int [] a = new int[3]) you obviously know the size of the array at compile time; it's 3.

Yes. Your correct.
3 * sizeOf(int) + array overhead.
You are reserving that much memory and then handing a pointer to the first position to your variable a. Then a can figure out how to index the array based on the location and size of what is being stored.

In your case the size of the array is 3.The number inside the square brackets is the size.CHeck this weeks tutorial about arrays on www.codejava.co.uk

Are you sure that book you are reading is about Java?
Unlike C/C++, Java does not have that dilemma - arrays are always allocated at runtime, even if you know their size during compile time.

Related

Memory saving in multi-dimentional array

Hi i need a multidimentional array to store big number but i am getting heap space error. I have 4gb ram.
double array[][] = new double[100000][100000]
I know it would need a lot of memory, can any one help me tackling this issue? Thanks for helping
If the array is sparse (more empty array cells than filled ones), you could look at using a hash map instead.
For the hash map, use the index of the array as the key.
example:
{ 23: 'foo', 23945: 'bar' }
this will be much more memory efficient!
If you absolutely need that much memory, you will need at minimum 100000*100000*8 B, or 80 GB of RAM (plus whatever overhead there is for the array organization itself). I will go as far as to say that you probably cannot work with that much data in RAM.
The only real way you'll be able to have an array that big is to write the parts of the array that aren't in use at a given moment in time out to disk. This will take some work to do though because you have to track where you are in the array to push and pull the array's data on the disk.

How to remove possible loss of precision error in java

here is a part of my code where I am getting error:
long p=1000000000-size-1;
long j;
for(j=p;j>p-k;j--)
{
sum2=sum2+sum[j];
}
System.out.print(sum2);
I think it is because I am using a long variable to define the size of array.
How could I deal with this error
Or if I am wrong please tell me how could I declare an array containing 10^10 elements.
Java does not provide a way to create arrays with size bigger than Integer.MAX_VALUE (which is about 2*10^9). Also are you sure you have enough memory to store such array? If you want to store array of 10^10 int values, you will need at least 40 Gb of RAM.
Change both the variables to int. If the values don't fit into an int the code won't work anyway.
I think it is because I am using a long variable to define the size of array. How could I deal with this error
No it isn't, because you aren't. You can't.
Aside from the the maximum array concerns and availability of enough virtual memory:
You have an integer literal 1000000000, but what you actually want is a long literal 1000000000L.

2D-Array : prefered way access items

So here I am tonight with this question that came up into my mind :
What is your favourite way to access the items of a m x n matrix
there is the normal way where you use an index for the columns
and another index for the rows matrix[i][j]
and there's another way where your matrix is a vector of length m*n
and you access the items using [i*n+j] as index number
tell me what method you prefeer most , are there any other methods
that would work for specific cases ?
Let's say we have this piece of C(++) code:
int x = 3;
int y = 4;
arr2d[x][y] = 0xFF;
arr1d[x*10+y] = 0xFF;
Where:
unsigned char arr2d[10][10];
unsigned char arr1d[10*10];
And now let's look at the compiled version of it (assembly; using debugger):
As you can see there's absolutely no penalty or slowdown when accessing array elements no matter if you're using 2D arrays or not, since both of the methods are actually the same.
There are only two reasons to go for the one-dimensional array to represent n-dimensions I can think of:
Performance: The usual way to allocate n-dimensional arrays means that we get n dimensions that may not necessarily be allocated in one piece - which isn't that great for spatial locality (and may also result in at least some additional memory accesses - in the worst case we need 1 additional read for each access). Now in C/C++ you can get around this (allocate memory in one piece, then afterwards specify the correct pointers; just be really careful not to forget this when you delete it) and other languages (C#) already can do this out of the box. Also note that in a language with a stop&copy GC the reasoning is unnecessary since all the objects will be allocated near each other anyhow. You avoid additional overhead for each single dimension though, so you use your memory and cache a bit better.
For some algorithms it's nicer to just use a one dimensional array which may make the code shorter and slightly faster - that's probably the one thing that can be argued as subjective here.
I think that if you need a 2D array, is because you would like to access it as a 2d array, not as a 1D array
Otherwise you can do a simple multiply to make it a 1D array
If I was to use a 2-D array, I would vote for matrix[i][j]. I think this is more readable. However, I might consider using Guava's Table class.
http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Table.html
I don't think that your "favourite" way, or the most aesthetically pleasing way is a good approach to take with this issue - underlying performance would be my main concern.
Storing a matrix as a contiguous array is often the most efficient way of doing matrix calculations. If you take a look at optimised BLAS (Basic Linear Algebra Subroutine) libraries, such as the Intel MKL, the AMD ACML, ATLAS etc etc contiguous matrix storage will be used. When contiguous storage is used, and contiguous data access patterns are exploited higher performance can result due to the improved locality-of-reference (i.e. cache performance) of the operations.
In some languages (i.e. c++) you could use operator overloading to achieve the data[i][j] style of indexing while doing the 1D array index mappings behind the scenes.
Hope this helps.

Storing multiple datatypes inside a single two dimensional array

I have a need to store multiple datatypes(like int or string mostly) inside a two dimensional array. Using Object[][] does solve the problem. But is it a good way to do so ??
How does the Object[][] array then reserve the heap space ? I mean, in accordance with which datatype? Does it leads to any wastage of resources ?
I was trying to do something like this:-
Object[][] dataToBeWritten={ {"Pami",34,45},
{"Ron","x",""},
{"spider","x",""}
};
Edit: You may suggest any better alternatives also if there exists any..
See How to calculate the memory usage of a Java array and Memory usage of Java objects: general guide.
For example, let's consider a 10x10 int array. Firstly, the "outer" array has its 12-byte object header followed by space for the 10 elements. Those elements are object references to the 10 arrays making up the rows. That comes to 12+4*10=52 bytes, which must then be rounded up to the next multiple of 8, giving 56. Then, each of the 10 rows has its own 12-byte object header, 4*10=40 bytes for the actual row of ints, and again, 4 bytes of padding to bring the total for that row to a multiple of 8. So in total, that gives 11*56=616 bytes. That's a bit bigger than if you'd just counted on 10*10*4=400 bytes for the hundred "raw" ints themselves.
I think this is for Hotspot only though. References to any object are, just link ints, 4 byte each, regardless of the actual object, or the object being null. Spare requirement for the objects themselves is a whole different story though, as the space isn't reserved or anything the like at array creation.
All objects are stored by reference. So a reference to the heap memory is stored. Therefore the amount of memory allocated for an array is one sizeof ( reference ) per entry.
An array of Objects is basically an array of pointers. However, that's what you get with any array of non-primitive types in Java - an array of Objects, and array of Strings, and an array of Robots of equal length take up the exact same amount of space. Heap space for the actual objects isn't allocated until you initialize the objects.
Alternative:
Use proper classes. You are trying to take some dynamic approach in a statically typed language. The thing is that Object[] doesn't help the reader of your code one bit what he is reading about. In fact I can't even suggest a design for a class because I can't make sense of your example. What is {"Pami",34,45} and how is this supposed to be related to {"spider","x",""}?
So supposed this information is something foo-like you should create a class Foo and collect all that stuff in a Foo[] or a List<Foo>.
Remember: Not only comments store information about your code. The type system contains valuable information about what you're trying to accomplish. Object contains no such information.

Do 2D arrays use more resources than 1D arrays in Java?

For example, would a full int[50][8] use more resources (RAM and CPU) than 8 full int[50] arrays?
In the first case you have one array object pointing to fifty array objects holding 8 int's.
So 1 + 50 array objects + fifty pointers in the first array object.
In the second case you have one array object pointing to 8 array objects holding 50 int's.
So 1 + 8 array objects + eight pointers in the first array object. Holding the int's is a wash.
There is not a good way to evaluate CPU usage for this.
There appears to be three things to compare here.
new int[50][8]
new int[8][50]
new int[400]
Now, I get this confused, but the way to remember is to think of new int[50][] which is valid.
So new int[50][8] is an array of 50 arrays of size 8 (51 objects). new int[8][50] is an array of 8 arrays of size 50 (9 objects). 9 objects will have a lower overhead than 51. new int[400] is just one object.
However, it at this size it probably doesn't make any measurable difference to the performance of your program. You might want to encapsulate the array(s) within an object that will allow you to change the implementation and provide a more natural interface to client code.
One additional useage point (came from a reference I unfortunately can't find now, but fairly commonsensical)-
The authors of this paper were testing various ways of compressing sparse arrays into mutidimensional arrays. One thing they noticed is that it makes a difference in terms of speed which way you iterate -
The idea was that if you have int[i][j] it was faster to do
for (i) {
for (j)
than to do
for (j) {
for (i)
because in the first instance you're iterating through elements stored contiguously.
you could tweak a tiny amout of memory by using an int[] myInt = int[400] array, and manually accessing an int at position (x,y) with myInt[x+y*50]
that would save you 50 32-bit pieces of memory. accessing it that way will maybe (who knows exactly what the hotspot compiler does to this..) take one more instruction for the multiplication.
that kind of micro-optimisation will most likely not make your app perform better, and it will decrease readability.
I suggest writing a small performance test for this with very large arrays to see the actual difference. In reality I don't think this would make the slightest difference.
int[50][8] is 50 arrays of length 8
int[8][50] is 8 arrays of length 50
int[400] is one array 400.
Each array has an overhead of about 16 bytes.
However, for the sizes you have here, it really doesn't matter. You are not going to be saving much either way.

Categories

Resources