0

我正在尝试获取算法消耗的内存,因此我创建了一组函数,它们会在 10 毫秒内停止执行,让我使用 getrusage() 函数读取内存。这个想法是设置一个计时器,该计时器将向进程发出警报信号,该信号将由处理程序 medir_memoria() 接收。

但是,程序在中间停止并显示以下消息:

[1]    3267 alarm    ./memory_test

读取内存的代码是:

#include "../include/rastreador_memoria.h"

#if defined(__linux__) || defined(__APPLE__) || (defined(__unix__) && !defined(_WIN32))

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <signal.h>
#include <sys/resource.h>

static long max_data_size;
static long max_stack_size;

void medir_memoria (int sig)
{
    struct rusage info_memoria;

    if (getrusage(RUSAGE_SELF, &info_memoria) < 0)
    {
        perror("Not reading memory");
    }

    max_data_size = (info_memoria.ru_idrss > max_data_size) ? info_memoria.ru_idrss : max_data_size;
    max_stack_size = (info_memoria.ru_isrss > max_stack_size) ? info_memoria.ru_isrss : max_stack_size;

    signal(SIGALRM, medir_memoria);
}

void rastrear_memoria ()
{
    struct itimerval t;

    t.it_interval.tv_sec = 0;
    t.it_interval.tv_usec = 10;
    t.it_value.tv_sec = 0;
    t.it_value.tv_usec = 10;

    max_data_size = 0;
    max_stack_size = 0;

    setitimer(ITIMER_REAL, &t,0);
    signal(SIGALRM, medir_memoria);
}

void detener_rastreo ()
{
    signal(SIGALRM, SIG_DFL);

    printf("Data: %ld\nStack: %ld\n", max_data_size, max_stack_size);
}

#else

#endif

main() 函数按以下顺序调用它们:

  1. rastrear_memoria()
  2. 我正在测试的算法的功能
  3. detener_rastreo()

我该如何解决这个问题?那个报警信息是什么意思?

4

1 回答 1

2

首先,将定时器设置为每 10 µs 响一次是乐观的,因为 10 微秒实际上是一个很小的时间间隔。尝试使用 500 µs(或者甚至可能是 20 毫秒,即 20000 µs)而不是首先使用 10 µs。

以 10 毫秒为单位停止执行

您已经编码了 10微秒,而不是毫秒!

然后,您应该交换这两行代码和代码:

signal(SIGALRM, medir_memoria);
setitimer(ITIMER_REAL, &t,0);

以便在第一个定时器响铃之前设置信号处理程序。

我猜你的第一个定时器在安装信号处理程序之前响起。仔细阅读signal(7)time(7)。的默认处理SIGALRM是终止。

顺便说一句,测量某些函数使用的时间的更好方法是clock_gettime(2)clock(3)。多亏了vdso(7)技巧,clock_gettime我的 i5-4690S 台式电脑能够在不到 50 纳秒的时间内获得一些时钟。

试图消耗内存

您可以考虑使用proc(5) ,例如快速 打开、读取和关闭/proc/self/status/proc/self/statm ....

(我猜你在 Linux 上)

顺便说一句,您的测量结果会让您失望:请注意,通常free(3)不会向内核释放内存(通过munmap(2) ...),而是简单地标记和管理该区域以供将来的 malloc(3)重用. 您可能会考虑mallinfo(3)malloc_info(3)但请注意它不是异步信号安全的,因此不能从信号处理程序内部调用。

(我倾向于认为您的方法存在严重缺陷)

于 2017-04-05T18:49:42.747 回答