Memory optimization with multidimensional arrays in Java

Yesterday I hit a memory limit while submitting a problem solution to an online judge. All because I used a wrong declaration of a multidimensional array. In case of C or C++ language this would not be a problem, but due to the fact that in Java everything is an object (despite primitive types), we should calculate allocated memory differently for multidimensional arrays.

For instance, in C++ the size of this array is 96 bytes (assuming we have 4-byte int):
int arr[2][3][4];
2 * 3 * 4 = 24. Plus 4 bytes for each due to int type and we get total of 24 * 4 = 96.
If we declare the array like this, result would be the same: int arr[4][3][2]

Let’s compare these two declarations in Java:
int arr[][][] = new int[40000][200][2];
int arr[][][] = new int[2][200][40000];

There is not much different from the data storage viewpoint, however the first one requires much more memory. Here is why:
1. Array in Java is an object itself. Every object (not near the reference, but in the heap) holds few additional bytes for the object header information. This header contains data necessary for the VM, which later uses it for the garbage collector or some other purposes. As far as I know, generally it takes 8 bytes in case of a 32-bit machine and 16 bytes in case of a 64-bit one. Apart from this, an object holds information about the array size – that’s additional 4 bytes. Also padding in memory might take few more bytes. So, I won’t start precise calculations and let’s assume that each array object (excluding array elements) takes X bytes.

2. int[a][b] – In Java language this is ‘a’ number of arrays which contain ‘b’ number of elements. I.e. we have a+1 number of objects instead of just one.
int[a][b][k] In case of a three-dimensional one a * b + a + 1 number of object, etc.

Now let’s calculate and compare sizes of these arrays:
(40,000 * 200 + 40,000 + 1) * X + (40,000 * 200 * 2 * 4)
(2 * 200 + 2 + 1) * X + (40,000 * 200 * 2 * 4)

Clearly, the second part, which calculates the total size of elements based on int type, will be the same. But according to the first part we will have 8,039,598 excessive objects in case of the first array, consequently it will take considerable larger memory.

By the way, I cannot see if this number is real with profiler, do you have any idea how to check this?

გამოხმაურება

comments

2 thoughts on “Memory optimization with multidimensional arrays in Java

  • Wednesday November 14th, 2012 at 03:21 AM
    Permalink

    მშვენიერი პოსტი, როგორც ყოველთვის. მე ეს ვიცოდი ადრე, მაგრამ დამაინტერესა პროფაილერით მაგის დამტკიცების ამბავი.
    ორაკლს აქვს ასეთი კარგი tool-ი – Java VisualVM. მაგით შეგიძლიათ ნებისმიერ ჯავა პროცესს მიუერთდეთ (მგონი სხვა მანქანაზეც კი, თუ გაშვებულია იქ რაღაც სერვერული ნაწილი) და ჩაიხედოთ რა ხდება ვირტუალური მანქანის იმ ინსტანციაში, რომელიც ამუშავებს ამ პროგრამას.
    ტესტებისთვის დავწერე მარტივი პროგრამა, რომელიც ითვლის პასკალის სამკუთხედის წესით Cnk-ებს. პირველ ვარიანტში 1000000×100-ზეა მასივი, მეორე შემთხვევაში პირიქით. გავუშვათ პროგრამები და VisualVM-ით დავუკავშირდეთ, გადავიდეთ Monitor გვერდზე და დავაჭიროთ Heap Dump ღილაკს.
    მოსალოდნელი სურათები დამხვდა:
    პირველი (ცუდი ვარიანტი):

    მეორე (კარგი):

    როგორც ჩანს პირველ ვარიანტში int[] ტიპიც ობიექტი მილიონზე მეტია და ზედმეტი 16 მეგაბაიტი გამოიყოფა, რაც არც ისე ცოტაა.

    ზოგადად მრავალგანზომილებიან მასივების აღწერა ჯერ პატარა და მერე დიდი განზომილებით წარმადობის მხრივაც კარგი იდეაა და ეს არა მარტო ჯავას ეხება. საქმე იმაშია, რომ მეხსიერება უფრო ეფექტურად მუშაობს როდესაც მიყოლებით განლაგებულ ელემენტებს მიმართავთ. პროგრამები საოლიმპიადო პრაქტიკიდან როგორც წესი შიდა ციკლებით დიდ განზომილებას მიმართავენ და თუ ეს იქნება პირველი განზომილება, მაშინ გამოდის რომ სულ აქა იქ მიმართავს პროცესორი და წარმადობა მნიშვნელოვნად ვარდება. დიახ, ამის გამო ჩამიგდია შეჯიბრზე სწორი ამოხსნა 🙂

    ისე სგ, კაი ამოცანა ამოგიხსნია 🙂

    Reply
  • Wednesday November 14th, 2012 at 01:41 PM
    Permalink

    მადლობა 🙂
    ისე მთლად ჩემი დამსახურებაა არაა მაგის ამოხსნა.

    Reply

Leave a Reply to Samurai Girl Cancel reply

Your email address will not be published. Required fields are marked *