2012-06-26 10 views
6

私は約600万行を返すクエリを持っています。これは大きすぎてメモリ内で一度にすべてを処理できません。どのように私はスカラーのデータ構造のサイズを近似することができますか?

各クエリはTuple3 [String、Int、java.sql.Timestamp]を返します。私は文字列がUTF8約20文字以上ではないことを知っています。

どのようにこれらのタプルの1つの最大サイズを調べることができますか、より一般的に、このようなスカラーデータ構造のサイズをどのように近似できますか?

私は使用しているマシンで6Gbを持っています。ただし、scala-queryをスカラーのリストに使用して、データベースからデータを読み取っています。

答えて

6

Scalaオブジェクトは、Javaオブジェクトとほぼ同じ規則に従っているため、これらの情報は正確です。 Here is one source、これは32ビットJVMの場合には少なくともほぼ正しいと思われます。 (64ビットJVMはポインタあたり8バイトを使用しますが、これは一般に4バイトの余分なオーバーヘッドと1ポインターあたり4バイトになりますが、JVMが圧縮ポインターを使用している場合は少なくなる可能性があります。

私は圧縮されたポインタがない(最悪の場合)64ビットマシンを仮定します。 Tuple3には、2つのポインタ(16バイト)+ Int(4バイト)+オブジェクトオーバーヘッド(〜12バイト)が最も近い8または32バイトに丸められ、余分なオブジェクト(8バイト)特別なバージョンInt。 (悲しいことに、タプルでプリミティブを使用する場合、ラップされたバージョンを使用する場合よりも、がさらにスペースを取ることになります)。 Stringは、32バイト、IIRC、および1文字あたり16 + 2のデータの配列です。 java.sql.Timestampは、Long(私はそうだと思います)の2つの値を格納する必要があります.32バイトです。すべてのことが言えば、それは約120バイト+文字あたり2つのオーダーであり、約20文字は〜160バイトです。

また、オブジェクトのサイズを直接測定する方法については、this answerを参照してください。このように測定すると、160バイトになります(このデータを使用して上記の見積もりが修正されていますので、前にいくつか小さなエラーがありました)。

+0

良い点、私は文字列とオブジェクトのオーバーヘッドの余分なオーバーヘッドを忘れていました。それでも、あまりデータはありません。 –

+0

String配列の文字あたり24を加えた理由はなぜですか? IIRCでは、配列は、非配列の場合は8バイト対4バイト、要素に加えて8バイトです。 @DanielC。 –

+0

Sobral - オブジェクトオーバーヘッドと長さがあり、64ビットマシンでは16バイトなので、少し離れていました。 –

2

あなたの処分でどれくらいのメモリがありますか?トリプルの600万のインスタンスは本当にあまりないです!

各参照には、32ビットまたは64ビット(圧縮された "oops"なしで実行しているかどうかによって異なります)のオーバーヘッドが4バイトまたは8バイトです。これはJDK7では32Gb未満のヒープではデフォルトです。

トリプルには3つのリファレンスがあります(特殊化のために余分なものがあるかもしれません)ので、Timestamplong(8バイト)のラッパー(リファレンス)です。 Intは特殊化されます(つまり、基礎となるint)。これにより、さらに4バイトが作成されます。 Stringは20 x 2バイトです。だから、基本的にの最悪の場合は、の1行あたり100バイトです。 1kbあたり10行、1Mbあたり10,000行。したがって、1Gb未満のヒープで600万行を快適に処理できます。

私はここで間違いを犯しました。このスペースでは、約20のフィールド(小数点や文字列などを含む)を毎日数百万行処理するからです。

+0

それについての見解はありますか? – matanster

関連する問題