1

データをバイナリに書き出すC++クラスがありますstd::ofstream。クラスはデータをとして保存していますboost:shared_arrayが、問題としてこれを排除しました。問題は、のへの呼び出しにwrite()ありofstreamます。

問題は、メモリがリークしているように見えることです。それが実行されているシステムはCentOS64ビット、GCC4.1.2です。

topアプリケーションが実行されていることをfree確認すると、実行可能ファイル自体はメモリを消費し続けません(Netbeansのメモリプロファイラによってバックアップされます)が、空きシステムメモリの量は時間の経過とともに減少します。さらに、アプリケーションが終了しても、このメモリは再利用されません。

これは特に問題です。これは、約50MB/秒で何時間も連続してディスクに書き出すことを目的としているためです。ただし、約90MBの空きシステムメモリに達すると、それは「安定化」し、それ以上減少しないように見え、アプリケーションは引き続き正常に実行されます。しかし、それは他の実行中のプロセスのためにシステムを台無しにします、それは悪いです、mmkay。

以下は、悲しみを引き起こしているクラスの非常にわずかに単純化されたバージョンです。

class WritableMessage
{
public:
    WritableMessage();
    void write(std::ofstream* const idxStream, std::ofstream* const dataStream);

private:
    IdxRecord m_idx;
    boost::shared_array<char> m_data;
};

ofstreamは初期化され、他の場所で破棄されますが、基本的には「永遠に」書き込むことができます。

void WritableMessage::write(std::ofstream* const idxStream, std::ofstream* const dataStream)
{
    //Call the IdxRecord to write itself (just a call to idxStream->write())
    m_idx.write(idxStream, dataStream->tellp());

    //This is the main issue, because this data can be up to about 2MB in size
    //for each write.  Commenting out this line removes all issues with the memory leak
    dataStream->write(m_data.get(), m_idx.getMessageSize());

    //I'd expect the flush to clear any buffers that the ofstream maintains,
    //but apparently not
    idxStream->flush();
    dataStream->flush();
}
4

2 に答える 2

4

問題はないようです。これは、システムキャッシュが意図したとおりに機能しているだけです。Linuxはキャッシュに対して非常に積極的であるため、これにはほとんどすべての空きメモリを使用しますが、アプリケーションがより多くのメモリを必要とするときはいつでも、そのメモリの一部を解放してアプリケーションに付与します。

于 2011-06-21T11:22:03.740 に答える
3

vmstatを使用する(マニュアルページ

vmstat -S m 1

キャッシュとバッファメモリが表示されます。バッファメモリは揮発性であり、アプリケーションが要求するとすぐに自動的に解放されることに注意してください。

ログインして「ddif=/ dev / sda of = / dev / null」を実行するだけで、8GBデスクトップ(Linux)への影響を簡単に示すことができます。バッファメモリは、使用可能なすべてのメモリを着実に消費します。

これは仕様によるものです

いくつかの関連リンク:

于 2011-06-21T11:30:44.327 に答える