Почему 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:
- Пакеты более 2G вряд ли поддерживаются ни MsysGit, ни Cygwin git.
- Объем памяти Cygwin по умолчанию слишком мал
- 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.