Size of 2d array in Java - java

I defined a 2d array in Java. As I read about it(i.e. 2d array), the first dimension of this 2d array is a pointer (I do not know that is it right or not, please tell me about it). So If I consider it as pointer, in a 64-bit system, what will be the size of below code after execution?
short [][] array1 = new short [10][];
short[][] array2 = new short[10][];
for (int i = 0; i < 10; i++)
array1[i] = new short[1];
for (int i = 0; i < 10; i++)
array2[i] = array1[i];
Please tell me about the size of above code.

For every one dimensional array you have a 24 byte overhead in addition to the space for the data in the array.
So your first two lines of code each create an array of 10 pointers - you are right about that - which take 8 bytes each on 64-bit system. This means you are allocating 2 * (24 + 10 * 8) = 208 bytes.
In the first for loop you are creating 10 arrays which are 24 + 2 * 10 = 44 bytes each. These are padded to at least 8 byte boundaries and thus take up 48 bytes or 480 bytes in total.
In the second loop, you are not allocating any new memory.
In total you are using 208 + 480 = 688 bytes.
Note that the actual usage depends on the JVM. For example:
Some JVMs compress pointers.
Some JVMs only use a 12 byte header for arrays.
In order to see the difference between outer and inner arrays it might be helpful to rewrite your code like this:
short[][] outerArray = new short[10][]; // Array of references to short arrays
short[] innerArray; // Array of shorts
for (int i = 0; i < 10; i++) {
innerArray = new short[1];
outerArray[i] = innerArray;
}

Related

Exception Java heap space

This is my code:
public static void runSGD(double[] R, double[][] theta, double convergenceTol)
{
List<Integer> allEdges = new ArrayList<Integer>(2*E);
for (int i = 0; i < 2*E; i++)
allEdges.add(i);
Collections.shuffle(allEdges, new Random(shuffleSeed));
double oldRes = calcObj(R, theta, allEdges), newRes = 0.0;
long numEdges = 0;
for (int _e = 0; _e < 2*E*tp; _e++) {
int e = allEdges.get(_e);
numEdges += weights.get(e);
}
if (verbose)
System.out.printf("[Info] Number of edges in training, including multiplicity = %d\n", numEdges);
int[][] edgeTable = new int[4][1<<30];
long part = 0; int cur = 0;
for (long i = 0; i < numEdges; i++) {
if (i+1 > part) {
part += weights.get(allEdges.get(cur));
cur++;
}
int row = (int) (i >>> 30);
int col = (int) (i & ((1 << 30) -1));
edgeTable[row][col] = allEdges.get(cur-1);
}
}
The error is Exception in thread "main" java.lang.OutOfMemoryError: Java heap space when run this code:
int[][] edgeTable = new int[4][1<<30];
I have try -Xmx1g,-Xmx3g, but didn't work ,how to fix it?
You are allocating 4 int[] arrays of 2^30 ints. That is 2^34 bytes or 16 gigabytes. Clearly that won't fit into a 1 or 3 gigabyte heap. Indeed, a typical laptop or PC won't have enough RAM for this ...
There is a secondary problem about whether the heap spaces are large enough to hold a 2^32 byte object, but it should be possible to address that if you can make the heap large enough.
In fact the JVM supports arrays of just under 2^31 elements; see Do Java arrays have a maximum size?, so the array size per se is not the problem here.
Arrays use ints to address single array elements. The maximum int-value is 2^31-1.
You create 4 Arrays of the size 2^30 which means you have 2^32 elements in your array.
Java does simple not support arrays of that size.
You can fix it by making 4 distinct arrays.
Also allocating 3GB with -Xmx3g wont help, since your array alone will need 16GB of RAM.
As others mentioned, you are trying to allocate huge arrays. You can try by allocating chunks of small array or try collections.

Loop leads to Timeout in array rotation

Hi how come swapping technique(my code) suffers Timeout where as circular array
{(i+number of rotation)%length} implementation does not?
a is an int[].
for (int i = 0; i < numberofrotation; i++) {
for (int j = 0; j < a.length-1; j++) {
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
return a;
(i+number of rotation)%length is to advance by number of rotations and wrap around to form circular array.
With modulo number of rotations are reduced to less than or equals to length of array, hence faster execution
To give you some idea...
Taking your approach of swapping array values,
if an array of length 10 is swapped by n times where n is a multiple of 10 ,
means n mod 10 = 0, than result is original array.
If value of n is not a multiple of 10 than you will see array order change in array values.
you can get the result either by rotating n times, or same result can be achieved by rotating n mod 10 times
So if n = 25 than swapping array by 25 is equivalent to swapping array 5 times
25 mod 10 = 5
similarly if n=13 , than swapping array by 13 time will have same result of swapping array 3 times
13 mod 10 = 3
Even if number of rotation is Integer.MAX_VALUE and length of array to rotate is 100,
number of rotations can be reduced to Integer.MAX_VALUE%100 which is 47.

Store data in real time in a 2D array in Java

I'm having trouble storing real time data in an array.
I have a 1D array that reads data in real time, this is fine and it's printing me data like this:
D/this is my array: arr: = [-1.43, -3.5916, 2.71, 4.42, -4.4, 0.0]
This data represents ONE sample, and I'm reading data 1000 samples per second, so if I print this array, it shows me reading per reading, I mean 1000 arrays like the picture (with different data) per second.
Now, I need to process that data, so I need to store the first 256 samples in a 2D array, process that array and then get a new one with the next 256 samples and so on.. But I haven't been able to do this.
transformed if my 1D array that shows me sample by sample. And buff is the matrix I want to store the data into.
This is how I get transformed, it is first short[] and then I'm converting it to double:
short[] yaxis = msg.getData().getShortArray(BiopluxService.KEY_FRAME_DATA);
double[] transformed = new double[yaxis.length];
for (int j = 0; j < yaxis.length; j++) {
transformed[j] = (double) yaxis[j];
}
This is what I have so far:
double[][] buff = new double[256][6];
for (int f = 0; f < 256; f++) {
buff[f] = transformed;
}
Log.d("this is my array", "arr: " + Arrays.deepToString(buff));
But my buff array has the same values.
Why doesn't the array contain different values
You are setting all the rows to point to the same array, if you run this code:
public class ClassNameHere {
public static void main(String[] args) {
double[][] d = new double[5][];
double[] row = {1,2,3};
for (int i = 0; i < 5; i++) {
d[i] = row;
}
}
}
Through this tool, you can see that at the end of this code all of the rows point to the exact same array, so they will all be equal.
How to fix
You want to create a new array for transformed each time, and then load into that array, so all the rows are different arrays, allowing them to have different values.

Break large 2D array into multiple smaller 2D array using JAVA

I have a 2D array which consist of image pixels which its size depends on the size of the input image. I need to break it into smaller 9x9 arrays. To give a clearer picture, I try to illustrate the situation:
//The number of rows and columns of the smallerArray will look something like this:
It should copy them from the imagePixels array iterating through each 8 columns, then move on to the next 8 rows.
1st small 2nd small 3rd small and so on..
array: array: array:
012345678 91011121314151617 181920212223242526 ....
0 0 0
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
7 7 7
8 8 8
Then move on to next 8 rows:
012345678 91011121314151617 181920212223242526 ....
9 9 9
10 10 10
11 11 11
12 12 12
13 13 13
14 14 14
15 15 15
16 16 16
17 17 17
.
.
.
I have done the following code but could not get my logic right. How can I stop the iteration:
Copy up until the 9th column or row, store it in an array, resume copying on the 10th column/row, stop when it reaches 9 column/row after, store it in another array, and keep on doing that till it finishes copying the imagePixels array.
I tried to store the arrays in an ArrayList so it would be easier for me to manipulate and do calculation stuffs with all the smallerArrays.
ArrayList<double[][]> collectionofSmallArrays = new ArrayList();
double[][] imagePixels = new double[1600][1000]; //Lets say this is the size of the image
double[][] smallerArray = new double[9][9];
for(int a = 0; a<smallerArray.length; a++)
{
for(int b =0; b<smallerArray[a].length; b++)
{
for(int c=0; c<imagePixels.length; c++)
{
for(int d=0; d<imagePixels[c].length; d++)
{
smallerArray[a][b] = imagePixels[c][d];
...(code to stop the iteration if it reaches 9, store it in array then resume where it stops with another new array)
collectionofSmallArrays.add(smallerArray);
}
}
}
}
Can anyone work around the code to achieve the expected result? Appreciate it.
You should probably provide more context information. Saying that an array of double values represents pixels sounds dubios. If you are working with images, then you might find solutions on a completely different level of abstraction (I'm thinking about BufferedImage#createSubImage here).
However, to answer the question: You should break the task up into smaller parts. Particularly, it might be easier to implement two methods:
One method that receives an input array, some coordinates, and an output array, and that copies the data from the specified coordinates of the input array to the output array
One method that calls the above mentioned method with the appropriate coordinates to split the whole array into the parts of the desired size.
In pseudocode:
for (each coordinates (9*r,9*c)) {
copy the rectange (9*r,9*c)-(9*r+9,9*c+9) of the input array into an array
A very simple implementation/test is shown in the following example. Note that this could be generalized and improved, but I think it shows the basic idea:
import java.util.ArrayList;
import java.util.List;
public class SubArrayTest
{
public static void main(String[] args)
{
double inputArray[][] = createInputArray(160, 100);
System.out.println("inputArray: "+toString(inputArray));
List<double[][]> subArrays = createSubArrays(inputArray, 9, 9);
for (double subArray[][] : subArrays)
{
System.out.println("subArray:\n"+toString(subArray));
}
}
private static List<double[][]> createSubArrays(
double inputArray[][], int subRows, int subCols)
{
List<double[][]> subArrays = new ArrayList<double[][]>();
for (int r=0; r<inputArray.length; r+=subRows)
{
for (int c=0; c<inputArray[r].length; c+=subCols)
{
double subArray[][] = new double[subRows][subCols];
fillSubArray(inputArray, r, c, subArray);
subArrays.add(subArray);
}
}
return subArrays;
}
private static void fillSubArray(
double[][] inputArray, int r0, int c0, double subArray[][])
{
for (int r=0; r<subArray.length; r++)
{
for (int c=0; c<subArray[r].length; c++)
{
int ir = r0 + r;
int ic = c0 + c;
if (ir < inputArray.length &&
ic < inputArray[ir].length)
{
subArray[r][c] = inputArray[ir][ic];
}
}
}
}
//===Test methods=========================================================
private static double[][] createInputArray(int rows, int cols)
{
double array[][] = new double[rows][cols];
for (int r=0; r<array.length; r++)
{
for (int c=0; c<array[r].length; c++)
{
array[r][c] = r*100+c;
}
}
return array;
}
private static String toString(double array[][])
{
String format = "%7.1f";
StringBuilder sb = new StringBuilder();
for (int r=0; r<array.length; r++)
{
for (int c=0; c<array[r].length; c++)
{
sb.append(String.format(format, array[r][c])+" ");
}
sb.append("\n");
}
return sb.toString();
}
}
Side notes:
You should always declare variables with their interface type. This means that you should not write
ArrayList<String> x = new ArrayList<String>();
but always
List<String> x = new ArrayList<String>();
In the posted code, you seemed to always add the same instance of the sub-array to the list. This means that in the end you would have many instances of the same array in the list, all with the same content. Somewhere in between you have to create a new double[9][9] array.
smallerArray[a][b] = imagePixels[c][d] line looks strange. You reuse same array instance. Your output array list will contain multiple reference to same array.
You cannot reuse smallerArray. Create the instance inside the for loop and store the size in a constant.
I think a map with some corner coordinates as a key would be far better than a list for storing your results.
What happens if the length or width or your image is not divisible by 9?

Arraylist in a Arraylist

How is it possible to store data (bytes) input like this:
input data (bytes) : 01 23 45 and 67 89 10
At the end Arraylist row : [[01,23,45],[67,89,10]]
// declaration
List<List<Byte>> row = new ArrayList<List<Byte>>();
List<Byte> myBytes = new ArrayList<Byte>();
int j=0;
// code before this defines the arraylengt to cut the buffer in pieces of 3 bytes
// and clears the Mybytes arraylist to be able to fill the buffer with new values
if(arrayLength > 0)
{
myBytes.add(value); // fill first arraylist (buffer) with byte value (for example: 01)
if(arrayLength == 1) // when buffer myBytes is full (with values 01 23 45) write value to position j in the new arraylist
{
row.add(j,new ArrayList<Byte>());
row.set(j,myBytes);
j +=j;
}
arrayLength -= 1; // for cutting the buffer in pieces of 3 bytes
}
Thank you for helping me !!
Just use an Arraylist with an Array of Bytes new ArrayList<Byte[]>();. It's a good way to produce a [n][3]-Matrix.
I'd suggest just using a matrix of size [n][3]. You can make sure that it stays as a byte by adding ifs, and must make it an int matrix that way it can have as many rows as you want.
I found the answer, use a arraylist to buffer the values convert to byte array and place them in a other arraylist. Thanks guys !
Note: Make shure u use myBytes.clear();
Here is my code:
if(bool == true)
{
myBytes.add(value); // buffer
if(arrayLength == 1)
{
byte[] data = new byte[myBytes.size()];
for (int i = 0; i < data.length; i++)
{
data[i] = (byte) myBytes.get(i);
}
row.add(data);
}
arrayLength -= 1;
}

Categories