-3

プロセス コア ダンプをデバッグしていますが、設計を変更したいと考えています。C++ プロセスは、eSQL/C を使用して Informix データベースに接続します。

現在、アプリケーションは、データベースから 2lacs を超える行をフェッチするクエリを使用しています。行ごとにnew、結果を使用して動的メモリを作成し、処理します。Out of memoryおそらく固有のメモリリークが原因で、エラーが発生することがあります。

データベースから一度に 500 行だけクエリを実行し、動的メモリを割り当てて処理するオプションを考えています。割り当てが解除されたら、次の 500 などをロードします。ただし、これにより、一度に必要な動的メモリが減少しても、DB クエリの数が増加します。

したがって、私の質問は、このオプションがスケーラブルなソリューションであるかどうかです。DB 呼び出しが増えるとアプリケーションのスケーラビリティが低下するかどうか。

4

4 に答える 4

1

クエリによって異なります。

現時点での 1 回の呼び出しで、20 万行すべてを返すには一定の時間がかかります。時間が DB の行数に比例するとしましょうn

新しい小さな呼び出しでも、DB 内の行数に比例して時間がかかることが判明した場合、全体的な操作には比例して時間がかかります (それぞれのコストで呼び出しn^2を行う必要があるため)。これはスケーラブルでない可能性があります。n / 500n

したがって、データベースに適切なインデックスが配置されていることを確認する必要があります (または、既にインデックスが作成されているフィールドの順序に従って、行を 500 のグループに分割することを確認してください)。呼び出しには、DB 内の行数ではなく、返される行数にほぼ比例して時間がかかります。それならスケーラブルかもしれません。

とにかく、メモリ リークがある場合、それはバグであり、"固有" ではなく、削除する必要があります。

于 2012-06-25T08:32:38.620 に答える
0

DB 呼び出しは、動的メモリ割り当てよりも確実にコストがかかります (どちらも高価ですが)。メモリ リークを修正できない場合は、この解決策を試して、効率を最大化するためにフェッチする行数を調整する必要があります。

とにかく、メモリリークは大きな問題であり、解決策は一時的なものです. スマートポインターを試してみてください。

于 2012-06-25T08:29:29.157 に答える
0

処理中にすべてのレコードをメモリに保持することは、少数のレコードを処理する場合を除き、あまりスケーラブルではありません。現在のソリューションがすでに失敗していることを考えると、ページングによって確実にスケーラビリティが向上します。ラウンドトリップを複数回行うと、ネットワークの遅延により遅延が大きくなりますが、ページングを使用すると、はるかに多くのレコードを処理できます。

とはいえ、メモリ リーク エラーは確実に解決する必要があります。メモリ不足の例外が引き続き発生するためです。例外が発生するポイントまでリークが蓄積するのに時間がかかるだけです。

さらに、ページング中にカーソルを開いたままにしないようにする必要があります。そうしないと、他のカーソルをブロックする問題が発生する可能性があります。一度に 1 ページのデータのみを返す SQL ステートメントを作成する必要があります。

于 2012-06-25T08:34:26.370 に答える
0

まず、メモリ リークがあるかどうかを特定し、ある場合は修正します。

メモリ リークはうまくスケーリングしません。

次に、動的メモリの割り当ては通常、DB アクセスよりもはるかに高速です。ただし、大量のメモリを割り当ててヒープを増やす必要がある場合を除きます。

処理を実行するために大量 (100k 以上の行) を要求している場合 - まず、これらすべてをフェッチする必要がある理由を自問してください- 基準に基づいて処理を実行するように SQL を変更できますか - 提供できる処理を明確にする場合これを行う方法についてのより良いアドバイス。

大量のデータを取得して処理するには、十分にスケーリングできるように適切に検討する必要があります。

于 2012-06-25T08:39:31.523 に答える