15

クロスプラットフォームの C++ コード (Windows、Mac) を書いています。現在のプロセスで使用されているメモリの量を確認する方法はありますか? 説明するための非常に不自然なスニペット:

unsigned long m0 = GetMemoryInUse();
char *p = new char[ random_number ];
unsigned long m1 = GetMemoryInUse();
printf( "%d bytes used\n", (m1-m0) );

もちろん、(m1-m0) は random_number と等しくなければなりませんが、メモリを割り当てる可能性のあるライブラリ呼び出しなど、より複雑なレベルでこれを実行しようとしています。

以下は好ましくありません。

  1. Valgrind (またはその同類) を使用する
  2. カスタム メモリ アロケータを使用して、割り当てられたメモリを追跡します。
4

4 に答える 4

18

移植可能な方法でこれを行うために私が書いたコードを次に示します。完璧ではありませんが、少なくともいくつかのプラットフォームのそれぞれでこれを行う方法へのポインタを与えるべきだと思います.

(追記:私は OSX と Linux を定期的に使用しており、これがうまく機能することを知っています。Windows を使用することはめったにないため、Windows 条項には警告が適用されますが、それは正しいと思います。)

#ifdef __linux__
# include <sys/sysinfo.h>
#endif

#ifdef __APPLE__
# include <mach/task.h>
# include <mach/mach_init.h>
#endif

#ifdef _WINDOWS
# include <windows.h>
#else
# include <sys/resource.h>
#endif

/// The amount of memory currently being used by this process, in bytes.
/// By default, returns the full virtual arena, but if resident=true,
/// it will report just the resident set in RAM (if supported on that OS).
size_t memory_used (bool resident=false)
{
#if defined(__linux__)
    // Ugh, getrusage doesn't work well on Linux.  Try grabbing info
    // directly from the /proc pseudo-filesystem.  Reading from
    // /proc/self/statm gives info on your own process, as one line of
    // numbers that are: virtual mem program size, resident set size,
    // shared pages, text/code, data/stack, library, dirty pages.  The
    // mem sizes should all be multiplied by the page size.
    size_t size = 0;
    FILE *file = fopen("/proc/self/statm", "r");
    if (file) {
        unsigned long vm = 0;
        fscanf (file, "%ul", &vm);  // Just need the first num: vm size
        fclose (file);
       size = (size_t)vm * getpagesize();
    }
    return size;

#elif defined(__APPLE__)
    // Inspired by:
    // http://miknight.blogspot.com/2005/11/resident-set-size-in-mac-os-x.html
    struct task_basic_info t_info;
    mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT;
    task_info(current_task(), TASK_BASIC_INFO, (task_info_t)&t_info, &t_info_count);
    size_t size = (resident ? t_info.resident_size : t_info.virtual_size);
    return size;

#elif defined(_WINDOWS)
    // According to MSDN...
    PROCESS_MEMORY_COUNTERS counters;
    if (GetProcessMemoryInfo (GetCurrentProcess(), &counters, sizeof (counters)))
        return counters.PagefileUsage;
    else return 0;

#else
    // No idea what platform this is
    return 0;   // Punt
#endif
}
于 2008-12-16T20:11:07.450 に答える
3

私はSIGAR APIを使用して、あらゆる種類のシステム関連情報を主要なプラットフォーム間で非常に移植可能に取得しました。これもオープンソース (Apache) です。これらの比較的些細だが退屈な作業を一からやり直す必要はまったくありません。

于 2008-12-16T20:33:37.403 に答える
2
  • それを行う移植可能な方法はありません。
  • ほとんどのオペレーティング システムでは、その OS に固有の信頼できる方法さえありません。
于 2008-12-16T19:57:27.367 に答える
2

「メモリプール」パターンを使用できます。プログラム内のすべてのオブジェクトは、このプールからメモリを割り当て/割り当て解除するため、消費するメモリの量を知ることができます。

于 2008-12-16T20:00:00.593 に答える