我在一个内存受限的嵌入式Linux设备上,通过HTTP将大文件(1Gb)传输到Qt中的服务器。当我第一次收到标题时,我确定在文件系统上写入数据的位置,创建一个指向该位置的QFile指针,然后打开要附加的文件。每次新数据到达套接字时,都会在服务器中调用“accumulate”函数。从那个累积函数我想通过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'。文档说这应该等到数据写入设备。
另外,如果我只取消注释'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缓存。看完这篇文章后 - &gt; http://blog.scoutapp.com/articles/2010/10/06/determining-free-memory-on-linux,我可能误解了'free -mt'的输出。我一直在观看该输出中的“免费”字段,看到它在大量文件传输时徘徊在2MB左右。我想在文件传输完成后看到它返回高级别的免费数据。
答案 0 :(得分:1)
我认为Linux只是缓存它可以解决的所有内容并释放它可以节省的2MB可用内存限制。在512 MB RAM系统上接收或发送~2Gb文件时,我的内存不会耗尽。在我的Qt程序中,在收到所有数据后,附加到文件,并关闭文件。我在QProcess中执行以下操作,在单独的终端中的'free -mt'命令中查看我的'free'内存返回:
// 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();