Почему 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 maxium установлен на 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' функция должна быть не в памяти и пытается запросить удвоение объема памяти... есть ли способ указать, сколько памяти потребуется запросить? или это зависит от реализации?

UPDATE2: При тестировании выделения памяти в 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.

Ответ 1

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

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

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

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

Ответ 2

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

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

От http://www.perlmonks.org/?node_id=541750

By default no Cygwin program can allocate more than 384 MB of memory 
(program+data). You should not need to change this default in most 
circumstances. However, if you need to use more real or virtual 
memory in your machine you may add an entry in the either the 
HKEY_LOCAL_MACHINE (to change the limit for all users) or
HKEY_CURRENT_USER (for just the current user) section of the registry.

Add the DWORD value heap_chunk_in_mb and set it to the desired 
memory limit in decimal MB. It is preferred to do this in Cygwin 
using the regtool program included in the Cygwin package. (For 
more information about regtool or the other Cygwin utilities, 
see the Section called Cygwin Utilities in Chapter 3 or use 
each the --help option of each util.) You should always be 
careful when using regtool since damaging your system registry
can result in an unusable system. 

Ответ 3

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

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

Ответ 4

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

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

  • Пакеты более 2G вряд ли поддерживается MsysGit и Cygwin Git
  • Общая память Cygwin по умолчанию количество слишком мало
  • 32bit Git является проблематичным

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

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

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

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

Двойная проверка, что MsysGit не установлен на компьютере Windows, можно использовать perl из MsysGit.

Переместил это репо обратно на компьютер Windows и поднял ограничение памяти Cygwin:

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

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

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

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