非常にメモリに制約のある組み込み Linux デバイス上の Qt のサーバーに HTTP 経由で大きなファイル ( 1Gb ) をストリーミングしています。最初にヘッダーを受け取ったときに、ファイル システムのどこにデータを書き込むかを決定し、その場所への QFile ポインターを作成し、追加するためにファイルを開きます。サーバーには、新しいデータがソケットに到着するたびに呼び出される「蓄積」機能があります。その蓄積関数から、write() を介してデータをファイルに直接ストリーミングしたいと考えています。私の蓄積機能を以下に示します。
私の問題は、これを行うときのメモリ使用量です-メモリが不足しています。蓄積の反復ごとに flush() および fsync() を実行でき、RAM の使用を心配する必要はありませんか? 私は何を間違っていますか?どうすれば修正できますか? ありがとう -
累積関数の前にファイルを 1 回開きます。
// Open the file
filePointerToWriteTo->open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Unbuffered)
以下は、蓄積関数の一部です。
// Extract the QFile pointer from the QVariant
QFile *filePointerToWriteTo = (QFile *)(containerForPointer->pointer).value<void *>();
qDebug() << "APPENDING bytes: " << data.length();
// Write to the file and sync
filePointerToWriteTo->write(data);
filePointerToWriteTo->waitForBytesWritten(-1);
filePointerToWriteTo->flush(); // Flush
fsync(filePointerToWriteTo->handle()); // Make sure bytes are written to disk
編集:
コードを計測すると、'waitForBytesWritten(-1)' 呼び出しは常に 'false' を返します。ドキュメントによると、データがデバイスに書き込まれるまで待機する必要があります。
また、「write(data)」行だけをコメント解除すると、空きメモリが減ることはありません。何が起こっているのでしょうか?「書き込み」はどのようにして大量のメモリを消費するのですか?
編集:
今、私は次のことをしています。メモリが不足することはありませんが、空きメモリが 2Mb に減少し、ファイル全体が転送されるまでそこにとどまります。その時点で、メモリが解放されます。途中で転送を強制終了すると、プロセスを再起動して同じファイルに書き込もうとするまで、約 2Mb の空き領域が残っているため、カーネルがメモリを保持しているように見えます。私はまだ、反復ごとにメモリを使用およびフラッシュできるはずだと思います。
// Extract the QFile pointer from the QVariant
QFile *filePointerToWriteTo = (QFile *)(containerForPointer->pointer).value<void *>();
int numberOfBytesWritten = filePointerToWriteTo->write(data);
qDebug() << "APPENDING bytes: " << data.length() << " ACTUALLY WROTE: " << numberOfBytesWritten;
// Flush and sync
bool didWaitForWrite = filePointerToWriteTo->waitForBytesWritten(-1); // <----------------------- This ALWAYS returns false!
filePointerToWriteTo->flush(); // Flush
fsync(filePointerToWriteTo->handle()); // Make sure bytes are written to disk
fdatasync(filePointerToWriteTo->handle()); // Specific Sync
sync(); // Total sync
編集:
この種のことは、私が Linux キャッシングを誤解しているように思えます。この投稿 --> http://blog.scoutapp.com/articles/2010/10/06/determining-free-memory-on-linuxを読んだ後、「free -mt」の出力を誤解している可能性があります。私はその出力の「空き」フィールドを監視しており、大規模なファイル転送で 2MB 前後に落ちているのを確認しています。ファイル転送が完了したら、高レベルの無料データに戻ることを望みます.