LINUX.ORG.RU
Ответ на: комментарий от Sylvia

а ТС где-то говорил о «левых» процессах? я не заметил…

arsi ★★★★★
()

ТС, вам для самой программы определить или сколько вообще памяти занято и свободно в системе?)

Sylvia ★★★★★
()
Ответ на: комментарий от Sylvia

Не проходит. С целью недопущения свопинга памяти, по достижению предопределенного порога процента занятости ОЗУ, программа сбрасывает на диск выходную информацию. На этапе накопления этой информации парсинг meminfo правильно показывает наращивание занятой памяти. Но после сброса на диск и, конечно, освобождения памяти, занимаемой сброшенной информацией, очередной парсинг meminfo не показывает уменьшение загрузки ОЗУ. Та же программа под Windows работает правильно, естественно, используя GlobalMemoryStatusEx для определения загруженности ОЗУ. Также я пробовал создать процесс, который выполнит команду «free», и считывал free-евский output, но сама free использует meminfo, так что проблема не «рассасывается». Другая попытка: создать процесс, который выполнит команду «sar -r 0», и считать его output. Опять та же ситуация. Так что не все так просто.

hvlad99
() автор топика
Ответ на: комментарий от arsi

Спасибо, но речь идет не об отдельном процессе, а о загруженности ОЗУ всеми процессами системы. Для большей детализации можете просмотреть мой ответ Sylvia-и.

hvlad99
() автор топика
Ответ на: комментарий от GArik

Увы... Картина та же. С другой стороны подкинули целую, неким написанную, функцию. Если сработает, то выложу исходник.

hvlad99
() автор топика

К сожалению, эта функция также анализирует /proc... . Такое ощущение, что разработчики операционки намеренно недопускают других разработчиков ко всей информации, либо где-то имеем бачок.

hvlad99
() автор топика
Ответ на: комментарий от hvlad99

1) - после free память в систему не сразу (или вообще не) отдается (только если юзать аллокатор потроенный на mmap)

2) - Вы возможно файловый кеш плюсуете к размеру памяти, на многих машинах под него уходит до 70% ОЗУ.

OxiD ★★★★
()
Ответ на: комментарий от OxiD

> 1) - после free память в систему не сразу (или вообще не) отдается (только если юзать аллокатор потроенный на mmap)

ЕМНИП, в glibc malloc как раз на mmap() основан.

DELIRIUM ☆☆☆☆☆
()
Ответ на: комментарий от OxiD

2). Я всего лишь хочу недопустить падения производительности (ее, по-моему, вызывает свопинг ОЗУ) путем отслеживания степени загруженности ОЗУ. Во всех вышеизложенных вариантах эта степень определялась как (totalmem-freemem)/totalmem*100 (получая процент загруженности), где все переменные получались так или иначе из /proc/... . Именно эти два значения (totalmem и freemem) и учитывались. 1). Как говорил один из персонажей «Ералаша»: «Книжки надо читать научные»... И был прав. Пока досконально не разберешься в организации памяти у Unix/Linux тяжело что-либо утверждать. Тем более программисту, воспитанному Windows - смотришь на работу «top» и видишь, что на запрос памяти (new или malloc) большая часть запрошенного выделяется из виртуальной памяти. Так что предположение о бачке, скорее всего, было скоропалительным. Надо разбираться.

hvlad99
() автор топика
Ответ на: комментарий от DELIRIUM

Даже если и на нем, это еще не значит что сразу после free будет munmap.

Помнится еще совсем недавно в firefox была пробелма с памятью, одно из решений которой было подключить malloc из OpenBSD через LD_PRELOAD.

OxiD ★★★★
()
Ответ на: комментарий от OxiD
oxid@home:~$ free -m
             total       used       free     shared    buffers     cached
Mem:          2026       1530        496          0         63        283

283 - кооличество мгабайт в кеше. При ьббольшой нагрузке это число может быть очень большим. Кеш не свопится, и при нехватке обычной памяти, он выбрасывается. Т.е для твоих расчетов можно считать что кеш это пустая память.

Но Если все это делается с целью снизить нагрузку, то надо учитывать - без кеша IO сильно буксует. При чем не хуже чем при своппинге.

OxiD ★★★★
()
Ответ на: комментарий от OxiD

Ребята! На данный момент, поскольку проект надо сдавать сегодня, принято решение сбрасывать output через каждые n MB. Конечно, сильно дробится выход и замедление на %. Конечно хотелось бы, все таки, иметь возможность получать ответ на вопрос: «Когда запрос памяти еще не приведет к падению производительности, с учетом того, что мой процесс не один в системе и должен быть некий запас (допустим k%), позволяющий моему процессу успеть (в случае захвата памяти другими процессами) сбросить output?» По всей видимости, именно так должен был быть поставлен вопрос изначально. Но сразу так, было бы слишком. Спасибо всем.

hvlad99
() автор топика
Ответ на: комментарий от hvlad99

я думаю, если не один - то в общем случае никак. сделай так чтобы он был один. Может в виртуальную машину его загнать? Ей жестко памяти выделить.

Вообще какая разница один или не один? ( Если памяти свободной осталось меньше 20%, то сбрасываем буферы..)

Линукс кстати свопится не всегда когда память совсем кончается. параметр vm.swappiness смотрите.

OxiD ★★★★
()

отключи своп. тормозов не будет. man swapoff

anonymous
()
Ответ на: комментарий от hvlad99

Может сделать параметр в конфиге (не использовать больше X мб памяти)? и не заниматься вычислениями доступной памяти, хорошего решения все равно нет.

amaora ★★
()
#define __STDC_FORMAT_MACROS
#include <inttypes.h>

#include <cstdio>

static const char * const PROC_MEMINFO = "/proc/meminfo";
static const char * const PROC_STAT    = "/proc/stat";

namespace
{

static void tagged_format_meminfo(char *buf, qint64 *mint)
{
    if(buf && mint)
    {
        sscanf(buf, "%" PRIu64, mint);
        *mint *= 1024;
    }
}

}

int memoryAllocated()
{
    if (!_procMemInfo.seek(0))
        return -1;

    char buf[160];
    bool tagged = false;

    qint64 total, used, x_used, free, shared, buffers, cached, slab, shmem;
    qint64 swap_total, swap_used;

    total = used = shmem = x_used = free = shared = buffers = cached = slab = 0LL;

    while(_procMemInfo.readLine(buf, sizeof(buf)) > 0)
    {
        if (buf[0] == 'M')
        {
            if(!strncmp(buf, "Mem:", 4))
                sscanf(buf + 5,
                    "%" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64,
                                &total, &x_used, &free,
                                &shared, &buffers, &cached);
            else if(!strncmp(buf, "MemTotal:", 9))
            {
                tagged_format_meminfo(buf + 10, &total);
                tagged = true;
            }
            else if(!strncmp(buf, "MemFree:", 8))
                tagged_format_meminfo(buf + 9, &free);
            else if(!strncmp(buf, "MemShared:", 10))
                tagged_format_meminfo(buf + 11, &shared);
        }
        else if(buf[0] == 'S')
        {
            if(!strncmp(buf, "Swap:", 5))
                sscanf(buf + 6,"%" PRIu64 " %" PRIu64, &swap_total, &swap_used);
            else if(!strncmp(buf, "SwapTotal:", 10))
                tagged_format_meminfo(buf + 11, &swap_total);
            else if(!strncmp(buf, "SwapFree:", 9))
                tagged_format_meminfo(buf + 10, &swap_used);
            else if(!strncmp(buf, "Slab:", 5))
                tagged_format_meminfo(buf + 6, &slab);
            else if(!strncmp(buf, "Shmem:", 6))
                tagged_format_meminfo(buf + 7, &shmem);
        }
        else if(!strncmp(buf, "Buffers:", 8))
            tagged_format_meminfo(buf + 9, &buffers);
        else if(!strncmp(buf, "Cached:", 7))
            tagged_format_meminfo(buf + 8, &cached);
    }

    if(tagged)
    {
        x_used = total - free;
        swap_used = swap_total - swap_used;
    }

    used = x_used - buffers - cached - slab + shmem;

    return ((double)used / (double)total) * 100;
}

Из проекта на С++, переделаешь сам. Я не уверен, что добавлять всю shmem к общей памяти правильно, но как по-другому я не знаю.

alex_custov ★★★★★
()
Ответ на: комментарий от hvlad99

Тут не свой аллокатор, тут просто типизированные указатели подойдут

/*
 * to the header
 */

#include <stdio.h>
#include <stdlib.h>

/* counting bytes in hype */
size_t hype_memory_used = 0;

/* sized wrapper around raw (void*) pointer */
typedef struct {
  size_t size;
  void*  raw_pointer;
} typed_pointer;

/*
 * allocation & free procedures
 */

typed_pointer*
xmalloc(size_t size) {

  /* wrapping allocated memory with `typed_pointer' */
  typed_pointer* typed_pointer = malloc(sizeof(typed_pointer));
  typed_pointer->raw_pointer   = malloc(size);

  /* check errors */
  if ((typed_pointer == NULL) || (typed_pointer->raw_pointer == NULL)) {
    fprintf(stderr, "Can't allocate memory anymore.");
    exit(-1);
  }

  /* counting bytes */
  typed_pointer->size = size;
  hype_memory_used   += size + sizeof(typed_pointer);

  return typed_pointer;
}

void
xfree(typed_pointer* typed_pointer) {

  /* uncounting bytes */
  hype_memory_used -= typed_pointer->size + sizeof(typed_pointer);

  /*free memory */
  free(typed_pointer->raw_pointer);
  free(typed_pointer);
}

#define XMALLOC(PP, P, T)                  \
  typed_pointer* PP = xmalloc(sizeof(T));  \
  T* P              = PP->raw_pointer

/*
 * for example
 */

typedef struct { int a; } foo;

int
main () {
  XMALLOC(foop, fooz, foo);

  fooz->a = 777;
  printf("%d\n", hype_memory_used);
  printf("%d\n", fooz->a);

  xfree(foop);

  printf("%d\n", hype_memory_used);
}

// =>
//
// 8
// 777
// 0

Количество занятой памяти в куче в байтах - hype_memory_used.

quasimoto ★★★★
()
Ответ на: комментарий от hvlad99

можно выделить достаточный «на все случаи жизни» размер памяти и запретить его помещать в своп. подойдёт?

arsi ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.