6

非常にメモリに制約のある組み込み 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 前後に落ちているのを確認しています。ファイル転送が完了したら、高レベルの無料データに戻ることを望みます.

4

1 に答える 1

1

Linux は、可能な限りすべてをキャッシュし、2MB の空きメモリ制限付近で確保できるものを解放しているだけだと思います。512 MB の RAM システムで最大 2Gb のファイルを送受信しても、メモリが不足することはありません。私のQtプログラムでは、すべてのデータを受信した後、ファイルに追加してファイルを閉じます。別のターミナルの「free -mt」コマンドで「空き」メモリが返されるのを確認するために、QProcess で次の操作を行います。

// Now we've returned a large file - so free up cache in linux
QProcess freeCachedMemory;
freeCachedMemory.start("sh");
freeCachedMemory.write("sync; echo 3 > /proc/sys/vm/drop_caches"); // Sync to disk and clear Linux cache
freeCachedMemory.waitForFinished();
freeCachedMemory.close();
于 2013-02-11T19:14:25.477 に答える