6

我正在一个内存非常有限的嵌入式 Linux 设备上通过 HTTP 将一个大文件 ( 1Gb ) 流式传输到我在 Qt 中的服务器。当我第一次收到标头时,我确定将数据写入文件系统的哪个位置,创建一个指向该位置的 QFile 指针,然后打开文件进行追加。服务器中有一个“累积”函数,每次新数据到达套接字时都会调用该函数。从那个累积函数中,我想通过 write() 将数据流式传输到文件中。您可以在下面看到我的累积功能。

我的问题是执行此操作时的内存使用情况——我的内存不足。我不应该能够在每次累积迭代中刷新()和 fsync(),而不必担心 RAM 的使用吗?我做错了什么,我该如何解决?谢谢 -

我在累积功能之前打开我的文件一次:

// 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”。文档说这应该等到数据写入设备。

此外,如果我只取消注释“写入(数据)”行,那么我的可用内存永远不会减少。会发生什么?“写”是如何消耗这么多内存的?

编辑:

现在我正在做以下事情。我没有用完内存,但我的可用内存下降到 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 程序中,在接收到所有数据后,附加到文件并关闭文件。我在 QProcess 中执行以下操作,以在单独的终端中的“free -mt”命令中查看我的“空闲”内存返回:

// 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 回答