2012-06-26 31 views
6

我有一個查詢返回大約600萬行,這太大,無法一次處理所有內存。如何近似scala中的數據結構的大小?

每個查詢返回一個Tuple3 [字符串,INT的java.sql.Timestamp]。我知道這個字符串永遠不會超過20個字符,即UTF8。

我怎樣才能制定出這些元組中的一個,以及更普遍的最大尺寸,我怎麼可以近似Scala的數據結構是這樣的規模?

我已經得到的6Gb我使用的機器上。但是,正在使用scala查詢將數據從數據庫中讀取到scala的列表中。

回答

6

Scala的對象大致遵循相同的規則作爲Java對象,等等這些的任何信息是準確的。 Here is one source,這對於32位JVM來說似乎至少是正確的。 (64位JVM每個指針使用8個字節,通常每個指針需要4個字節的額外開銷加上4個字節 - 但是如果JVM使用壓縮指針,可能會少一些,我認爲它默認使用壓縮指針。)

我假定在64位計算機不啓動壓縮指針(最壞情況);然後一個Tuple3有兩個指針(16個字節)加上一個Int(4字節)加上對象開銷(〜12個字節)四捨五入到最接近的8或32個字節,加上一個額外的物體(8個字節)作爲非存根專業版Int。 (不幸的是,如果你在元組中使用原語,它們甚至比使用包裝版本時更多地使用空間)。 String是32字節,IIRC,加上數據的數組是16加2每個字符。 java.sql.Timestamp需要存儲幾個Long s(我認爲是),所以這是32個字節。總而言之,它的大小約爲120個字節加上每個字符兩個,大約20個字符大約爲160個字節。

或者,請參閱this answer以獲取直接測量對象大小的方法。當我用這種方法測量時,我得到了160個字節(並且使用這個數據校正了上面的估計,所以它匹配;之前我有幾個小錯誤)。

+0

好點,我忘了String加對象開銷的額外開銷。不過,這不是很多數據。 –

+0

爲什麼在String數組上每個字符加24個字符? IIRC,數組是8個字節,而非數組則是4個字節,再加上元素。 –

+0

@DanielC。Sobral - 在64位計算機上有16個字節的對象開銷加上長度,所以我稍微偏離了一點。 –

2

您有多少內存供您使用?一個三元組的600萬個實例並不是很多!

每個引用的開銷是4或8個字節,具體取決於您是在運行32位還是64位(沒有壓縮的「oops」,儘管這是JDK7中32Gb以下堆的默認值)。

所以你的三元組有3個引用(由於專業化可能會有額外的引用 - 所以你可能會得到4個引用),你的Timestamp是圍繞long(8字節)的封裝(引用)。你的Int將是專門的(即一個潛在的int),所以這使得另外4個字節。字符串是20 x 2字節。所以你基本上有的最壞情況,在下每行100字節;所以每kb 10行,每Mb 10,000行。所以你可以在1Gb的堆中輕鬆處理你的600萬行。

坦率地說,我認爲我在這裏犯了一個錯誤,因爲我們每天在這個空間中每天處理大約20個字段(包括小數點,字符串等)的數百萬行。

+0

有什麼事後看? – matanster