Почему Git.pm на cygwin жалуется на "Недостаточно памяти во время" большого "запроса?

Я получаю эту ошибку при выполнении git svn rebase в cygwin

Out of memory during "large" request for 268439552 bytes, total sbrk() is 140652544 bytes at /usr/lib/perl5/site_perl/Git.pm line 898, <GEN1> line 3.

268439552 - 256 МБ. Максимальный объем памяти Cygwin установлен на 1024 МБ, поэтому я предполагаю, что он имеет другой максимальный объем памяти для perl?

Как я могу увеличить максимальный объем памяти, который могут использовать perl-программы?

обновление: это где ошибка происходит (в Git.pm):

 while (1) {
      my $bytesLeft = $size - $bytesRead;
      last unless $bytesLeft;

      my $bytesToRead = $bytesLeft < 1024 ? $bytesLeft : 1024;
      my $read = read($in, $blob, $bytesToRead, $bytesRead); //line 898
      unless (defined($read)) {
         $self->_close_cat_blob();
         throw Error::Simple("in pipe went bad");
      }

      $bytesRead += $read;
   }

Я добавил печать перед строкой 898, чтобы распечатать $bytesToRead и $bytesRead, и в результате получилось 1024 для $bytesToRead и 134220800 для $bytesRead, поэтому он читает 1024 байта за раз и уже прочитал 128 МБ. Функция Perl'read' должна быть не в памяти и пытается запросить удвоение своего объема памяти... есть ли способ указать, сколько памяти запрашивать? или это зависит от реализации?

ОБНОВЛЕНИЕ2: во время тестирования выделения памяти в cygwin: объем этой программы на C составил 1536 МБ

int main() {
   unsigned int bit=0x40000000, sum=0;
   char *x;

   while (bit > 4096) {
      x = malloc(bit);
      if (x)
         sum += bit;
      bit >>= 1;
   }
   printf("%08x bytes (%.1fMb)\n", sum, sum/1024.0/1024.0);
   return 0;
}

Хотя эта Perl-программа аварийно завершала работу, если размер файла превышал 384 МБ (но выполнялась успешно, если размер файла был меньше).

open(F, "<400") or die("can't read\n");
$size = -s "400";

$read = read(F, $s, $size);

Ошибка похожа

Out of memory during "large" request for 536875008 bytes, total sbrk() is 217088 bytes at mem.pl line 6.

4 ответа

Решение

Эта проблема была решена kongo2002 в последней версии kongo2002. Доступен патч. Проблема в том, что в Git.pm файл читается за один раз. Решение состоит в том, чтобы прочитать это маленькими кусками. Я не уверен, что исправление вошло в какие-либо выпущенные версии, но его легко применить локально.

Вам нужно изменить C:\Program Files\Git\lib\perl5\site_perl\Git.pm (смена около 8 строк). Сначала убедитесь, что вы это сделали.

Подробности о том, что делать, смотрите в Git.pm: используйте потоковую запись в cat_blob ().

Оригинальное обсуждение - Проблемы с большими файлами "Недостаточно памяти".

Вы пытались увеличить общую полезную память Cygwin?

Это сообщение показывает, что Perl уже был до 130 МБ (всего sbrk()), а затем попытался запросить дополнительные 256 МБ, что не удалось.

С http://www.perlmonks.org/?node_id=541750

По умолчанию ни одна программа Cygwin не может выделить более 384 МБ памяти (программа + данные). Вам не нужно менять это значение по умолчанию в большинстве случаев. Однако, если вам нужно использовать больше реальной или виртуальной памяти на вашем компьютере, вы можете добавить запись в разделе реестра HKEY_LOCAL_MACHINE (чтобы изменить ограничение для всех пользователей) или в HKEY_CURRENT_USER (только для текущего пользователя). Добавьте значение DWORD heap_chunk_in_mb и установите желаемый предел памяти в десятичных МБ. Это предпочтительно делать в Cygwin с помощью программы regtool, включенной в пакет Cygwin. (Для получения дополнительной информации о regtool или других утилитах Cygwin см. Раздел "Служебные программы Cygwin" в главе 3 или используйте каждый параметр --help каждой утилиты.) При использовании regtool всегда следует соблюдать осторожность, поскольку повреждение системного реестра может привести к непригодная система. 

Это не специфичная для Perl проблема, а скорее проблема, связанная с cygwin. Вы можете увеличить выделение памяти с помощью ulimit,

Какую версию Git вы используете? Если вы не пользуетесь последней версией, это может быть неэффективностью, которая была исправлена ​​в последней версии (например, просмотр большого файла с foreach скорее, чем while, как Google предлагает, когда я сделал быстрый поиск.)

Решение с максимизацией памяти Cygwin на самом деле не работает.

В настоящее время есть две проблемы с Git на Windows:

  1. Пакеты более 2G вряд ли поддерживаются ни MsysGit, ни Cygwin git.
  2. Объем памяти Cygwin по умолчанию слишком мал
  3. 32bit Git проблематичен

Что я сделал шаг за шагом:

Я перенес свое git-репо на Unix-машину, установил следующие конфиги:

[pack]
        threads = 2
        packSizeLimit = 2G
        windowMemory = 512M

После этого я сделал git gc и все пакеты были восстановлены до 2G.

Дважды проверил, что MsysGit не установлен на машине с Windows, можно использовать другой способ Perl из MsysGit.

Перенес этот репо обратно на Windows Machine и увеличил лимит памяти Cygwin:

regtool -i set /HKLM/Software/Cygwin/heap_chunk_in_mb 1536

Было важно установить память Cygwin выше, чем pack.windowMemory×pack.threads и не выше 1,5 г

Итак, первые две проблемы теперь решены. Но третий нет.

К сожалению, это не работает на окнах. Во время некоторых перепаковок иногда происходит сбой из-за нехватки памяти. Даже с threads = 1 а также pack.windowMemory = 16M а максимальная глубина и дельта установлены на 250.

Другие вопросы по тегам