Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java array with more than 4gb elements

Tags:

I have a big file, it's expected to be around 12 GB. I want to load it all into memory on a beefy 64-bit machine with 16 GB RAM, but I think Java does not support byte arrays that big:

File f = new File(file); long size = f.length(); byte data[] = new byte[size]; // <- does not compile, not even on 64bit JVM 

Is it possible with Java?

The compile error from the Eclipse compiler is:

Type mismatch: cannot convert from long to int 

javac gives:

possible loss of precision found   : long required: int          byte data[] = new byte[size]; 
like image 664
Omry Yadan Avatar asked May 18 '09 15:05

Omry Yadan


People also ask

What is the maximum array size in Java?

The 32-bit Java int can go to a maximum of 2,147,483,647, so that is the theoretical maximum Java array size. However, virtual machines for different operating systems may not allocate every available bit to the elements in the Java array.

What happens if you exceed the size of an array in Java?

If you try to access the array position (index) greater than its size, the program gets compiled successfully but, at the time of execution it generates an ArrayIndexOutOfBoundsException exception.

Can you increase array size in Java?

If you want to change the size, you need to create a new array of the desired size, and then copy elements from the old array to the new array, and use the new array. In our example, arr can only hold int values. Arrays can hold primitive values, unlike ArrayList, which can only hold object values.


2 Answers

Java array indices are of type int (4 bytes or 32 bits), so I'm afraid you're limited to 231 − 1 or 2147483647 slots in your array. I'd read the data into another data structure, like a 2D array.

like image 63
Bill the Lizard Avatar answered Oct 19 '22 13:10

Bill the Lizard


package com.deans.rtl.util;  import java.io.FileInputStream; import java.io.IOException;  /**  *   * @author [email protected]  *  * Written to work with byte arrays requiring address space larger than 32 bits.   *   */  public class ByteArray64 {      private final long CHUNK_SIZE = 1024*1024*1024; //1GiB      long size;     byte [][] data;      public ByteArray64( long size ) {         this.size = size;         if( size == 0 ) {             data = null;         } else {             int chunks = (int)(size/CHUNK_SIZE);             int remainder = (int)(size - ((long)chunks)*CHUNK_SIZE);             data = new byte[chunks+(remainder==0?0:1)][];             for( int idx=chunks; --idx>=0; ) {                 data[idx] = new byte[(int)CHUNK_SIZE];             }             if( remainder != 0 ) {                 data[chunks] = new byte[remainder];             }         }     }     public byte get( long index ) {         if( index<0 || index>=size ) {             throw new IndexOutOfBoundsException("Error attempting to access data element "+index+".  Array is "+size+" elements long.");         }         int chunk = (int)(index/CHUNK_SIZE);         int offset = (int)(index - (((long)chunk)*CHUNK_SIZE));         return data[chunk][offset];     }     public void set( long index, byte b ) {         if( index<0 || index>=size ) {             throw new IndexOutOfBoundsException("Error attempting to access data element "+index+".  Array is "+size+" elements long.");         }         int chunk = (int)(index/CHUNK_SIZE);         int offset = (int)(index - (((long)chunk)*CHUNK_SIZE));         data[chunk][offset] = b;     }     /**      * Simulates a single read which fills the entire array via several smaller reads.      *       * @param fileInputStream      * @throws IOException      */     public void read( FileInputStream fileInputStream ) throws IOException {         if( size == 0 ) {             return;         }         for( int idx=0; idx<data.length; idx++ ) {             if( fileInputStream.read( data[idx] ) != data[idx].length ) {                 throw new IOException("short read");             }         }     }     public long size() {         return size;     } } } 
like image 41
William Deans Avatar answered Oct 19 '22 12:10

William Deans