簡體   English   中英

如何在以下代碼中減少 memory 的使用?

[英]How i can reduce the memory usage in following code?

import java.util.List; 
class Solution {
    public List<Boolean> kidsWithCandies(int[] candies, int extraCandies) {
        List<Boolean> result = new ArrayList<>();
        int highest = 1;
        for(int i = 0 ; i < candies.length ; i++){
            if(candies[i] > highest)
                highest = candies[i];
        }
        for(int i = 0 ; i < candies.length ; i++){
            result.add((candies[i] + extraCandies) >= highest); 
        }
        
        return result;
    }
}

我必須嘗試解決糖果最高的孩子的問題。 上面的代碼顯示了 memory 的使用量為 38.9 MB。 我怎樣才能進一步減少它。 請幫助我了解這個過程是如何工作的。

你的代碼已經足夠緊湊了。 你只能做兩件事:

  1. 使用位集
  2. 使用 Array 代替 List,因為您知道數組的大小。

解釋:

  1. booleanBitSet

boolean

為了存儲和操作 arrays 位,有人可能會爭辯說我們應該使用boolean[]作為我們的數據結構。 乍一看,這似乎是一個合理的建議。

為了使事情更具體,讓我們看看具有 1024 個元素的 boolean[] 消耗了多少空間:

boolean[] bits = new boolean[1024];
System.out.println(ClassLayout.parseInstance(bits).toPrintable());

理想情況下,我們期望該陣列具有 1024 位 memory 占用空間。 然而,Java Object 布局 (JOL) 揭示了一個完全不同的現實:

[Z object internals:
 OFFSET  SIZE      TYPE DESCRIPTION            VALUE
      0     4           (object header)        01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4           (object header)        00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4           (object header)        7b 12 07 00 (01111011 00010010 00000111 00000000) (463483)
     12     4           (object header)        00 04 00 00 (00000000 00000100 00000000 00000000) (1024)
     16  1024   boolean [Z.                    N/A
Instance size: 1040 bytes

如果我們忽略 object header 的開銷,則數組元素消耗 1024 字節,而不是預期的 1024 位。 這比我們預期的多 700% memory。

BitSet讓我們將一個 1024 位的 BitSet 實例的 memory 占用空間與我們之前看到的 boolean[] 進行比較:

BitSet bitSet = new BitSet(1024);

System.out.println(GraphLayout.parseInstance(bitSet).toPrintable());

這將打印 BitSet 實例的淺大小及其內部數組的大小:

java.util.BitSet@75412c2fd object externals:
          ADDRESS       SIZE TYPE             PATH         VALUE
        70f97d208         24 java.util.BitSet              (object)
        70f97d220        144 [J               .words       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

如上所示,它在內部使用具有 16 個元素(16 * 64 位 = 1024 位)的 long[]。 無論如何,這個實例總共使用了 168 個字節,而 boolean[] 使用了 1024 個字節。

更多詳情請點擊這里

  1. ArrayListArray

數組 memory 在創建時分配。 當我們初始化一個數組時,它會根據數組的大小和類型分配memory。 它使用引用類型的 null 值和原始類型的默認值初始化所有元素。

ArrayList 隨着 memory 分配的增長而更改。 當我們在初始化 ArrayList 時指定容量時,它會分配enough memory來存儲達到該容量的對象。 邏輯大小保持為 0。當需要擴展容量時,會創建一個新的更大的數組,並將值復制到其中。

因此,ArrayList(List) 比簡單的 Arrays 需要更多的 memory 消耗。

更多詳情請點擊這里


修改后的內存優化版本:

public BitSet kidsWithCandies(int[] candies, int extraCandies) {
    BitSet bitSet = new BitSet(candies.length);
    int highest = Integer.MIN_VALUE;
  
    for(int i = 0 ; i < candies.length ; i++){
        if(candies[i] > highest)
            highest = candies[i];
    }
    
    for(int i = 0 ; i < candies.length ; i++){
        bitSet.set(i,(candies[i] + extraCandies) >= highest );
    }
    
    return bitSet;
}    

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM