2012-11-13 44 views
5

私はバーストでログインし、データパスを最適化するためにたくさんのものを書いています。私はStringBuilderでログテキストを構築します。何が最も効率的な初期容量、メモリ管理が賢明なので、それはJVMに関係なくうまくいくでしょうか?目標は、ほとんどの場合、80〜100程度の初期容量でカバーする必要があります再割り当てを避けることです。しかし、私はまた、StringBuilderインスタンスがバッファー内でハングアップする可能性があり、無駄なバイトが詰まるので、できるだけ少ないバイト数を無駄にしたい。StringBuilderの最も効率的な初期容量サイズですか?

私はこれがJVMに依存していることを認識していますが、JVMにかかわらず最小のバイトを無駄にする価値があるはずです。私は現在、128-16を使用しています。ここで128は素敵な丸数字で、減算は割り当てオーバーヘッドです。また、これは "時期尚早の最適化"のケースと考えられますが、私が後にしている答えは "親しみ感のあるルール"なので、将来的にも役立つことがわかっています。

「私の最高の推測」の回答は期待していません(自分の答えはすでにそれです)。誰かがこれを既に調査して知識ベースの回答を共有してくれることを願っています。

+0

この質問への回答は、例えば、テキストが「StringBuilder」などにどれくらい保存されているかなど、多くのことに依存します。メモリやCPUプロファイラを使用してmeasureを調べる唯一の方法があります。数十万の 'StringBuilder'オブジェクトを作成しない限り、数バイトを心配する必要はありません。 – Jesper

+1

これまでの最大のオーバーヘッドはIOのコストです。このデータをIOに書き込むつもりがない限り、私はそれを心配しません。 –

答えて

3

さて、私はこれを簡単に自分でテストしてから、コメントの後にもう少しテストして、この編集された答えを得ました。 VM名を報告JDK 1.7.0_07およびテストアプリケーションを使用し

"は、Java HotSpot(TM)64ビットサーバーVM"、StringBuilderメモリ使用量の粒状も4文字で増加し、4つの文字あります。

回答:の任意の倍数は、少なくともこの64ビットJVMでメモリ割り当ての観点からStringBuilderに同等の良い容量です。

異なる初期容量を持つ1000000個のStringBuilderオブジェクトを作成し、異なるテストプログラムの実行で(同じ初期ヒープ状態を持つように)テストし、前後にManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed()を出力してテストします。

StringBuilderのバッファごとに実際にヒープから割り当てられた量は、Java charが2バイトの長さであるため、期待どおり8バイトの偶数倍です。換言すれば、最初の容量が1.00である1000000個のインスタンスを割り当てると、初期容量が5 ... 8である同じ数の等間隔を割り当てるよりも、約8メガバイト少ないメモリ(インスタンス当たり8バイト)が必要となる。

+0

テスト手順を共有してもよろしいですか? - そのような粒度でヒープの使用量をどのように決定するのですか? – JimmyB

+0

コードは手軽ですが、ヒープの使用量はStringBuilderの初期容量で4単位増加するたびに増加し、次の3サイズでほぼ同じになり、4の次の倍数に再びジャンプします。 **しかし、**は4バイトで、8バイトを意味します。質問してくれてありがとう、私は明日これを確かめるために明日再びテストします。 – hyde

+0

ヒープ使用量が1000000 x 4バイト単位で増加しているのを確認しましたか? - 私は[データ構造体]が占めるJavaヒープ領域のバイト数を見積もり、Javaプログラムではchar型ではなく、他の値/型でないと見積もることを考えません。また、ヒープの割り当て*細分性に関係なく、GCがヒープにメモリを解放することを決める粒度は不明であり、測定に影響を与えます。 - あなたが好奇心からテストをしている、あるいは与えられたJVMのいくつかの特性を測定しているなら、進んでください。 - そうでなければ...上記の私の答えを見てください:) – JimmyB

4

この場合はスマートにしないでください。

私は現在、128-16を使用しています。ここで128は素敵な丸数字で、減算は割り当てオーバーヘッドです。

Javaでは、これはJVMの内部動作に関する完全に恣意的な前提に基づいています。 JavaはCではありません。バイトアライメントなどは、ではなく、で、プログラマーが悪用しようとする可能性のある問題です。

文字列の最大長を知っている場合は、初期サイズとして使用できます。それとは別に、最適化の試みは無駄です。

あなたは本当に、あなたのStringBuilder秒の膨大な量は、(かなりのロギングの概念に適合していない)、非常に長い期間のために周りになることを知っあなたが本当にJVMを説得しようとする必要性を感じた場合はヒープスペースのいくつかのバイトを節約するために、文字列が完全に構築された後で、trimToSize()を試してみてください。しかし、文字列がメガバイトを無駄にしない限り、実際にはアプリケーションの他の問題に集中する必要があります。

関連する問題