Есть ли способ ограничить объем памяти, который использует "git gc"?

Я размещаю git-репо на общем хосте. В моем репо обязательно есть несколько очень больших файлов, и каждый раз, когда я пытаюсь запустить "git gc" в репо, мой процесс прерывается провайдером общего хостинга за использование слишком большого количества памяти. Есть ли способ ограничить объем памяти, который может потреблять git gc? Я надеюсь, что он сможет обменивать использование памяти на скорость и займет немного больше времени для своей работы.

5 ответов

Решение

Да, посмотрите на страницу справки для git config и посмотрите на pack.* варианты, в частности pack.depth, pack.window, pack.windowMemory а также pack.deltaCacheSize,

Это не совсем точный размер, так как git нужно отобразить каждый объект в память, чтобы один очень большой объект мог вызвать много использования памяти независимо от настроек окна и дельта-кэша.

Возможно, вам повезет лучше упаковать локально и перенести файлы пакета на удаленную сторону "вручную", добавив .keep файлы, так что удаленный Git никогда не пытается полностью перепаковать все.

Я использовал инструкции по этой ссылке. Та же идея, что и CB Bailey.

Копия команд находится здесь:

git config --global pack.windowMemory "100m"
git config --global pack.packSizeLimit "100m"
git config --global pack.threads "1"

Это работало для меня на hostgator с учетной записью общего хостинга.

Использование памяти Git Repack: (pack.deltaCacheSize + pack.windowMemory) × pack.threads, Соответствующие значения по умолчанию: 256 МБ, без ограничений, nproc.

Дельта-кеш бесполезен: большую часть времени тратится на вычисление дельт на скользящем окне, большая часть которого отбрасывается; кэширование оставшихся в живых, чтобы их можно было повторно использовать один раз (при записи), не улучшит время выполнения. Этот кеш также не разделяется между потоками.

По умолчанию память окна ограничена pack.window (gc.aggressiveWindow). Ограничивать упаковку таким образом - плохая идея, потому что размер рабочего набора и эффективность будут сильно различаться. Лучше поднять как до гораздо более высоких значений, так и полагаться на pack.windowMemory ограничить размер окна.

Наконец, многопоточность имеет недостаток разделения рабочего набора. снижение pack.threads и увеличивается pack.windowMemory так что общее число остается неизменным, должно улучшить время выполнения.

У repack есть и другие полезные настройки (pack.depth, pack.compressionпараметры растрового изображения), но они не влияют на использование памяти.

Git 2.18 (Q2 2018) улучшит потребление памяти gc.
До 2.18 " git pack-objects "необходимо выделить тонны" struct object_entry "при выполнении своей работы: уменьшение его размера значительно повышает производительность.
Это влияет git gc,

См. Коммит f6a5576, коммит 3b13a5f, коммит 0aca34e, коммит ac77d0c, коммит 27a7d06, коммит 660b373, коммит 0cb3c14, коммит 898eba5, коммит 43fa44f, коммит 06af3bb, коммит b5c0cbd, коммит 0c6804a, коммит fddbbbbbbb1 0b6c1, коммит 0c6804a, коммит fd9cbbbbbbbbc1 ( 0, fbdbcbcbbbc), коммит fca3b5, коммит b3c5cbd, коммит 0c6804a, коммит fd9bc4, fbdcbbbbbb1, bd, fbdcbbb1, bb1, fd9b6, bb, fd9b6, bd, fb, db, bb, fb, fd, bb, bd, fb, db, bb, fd, fb, db, bb, cd, f3a5576. Нгуен Тай Нгук Дуй ( pclouds )
(Объединено Юнио С Хамано - gitster - в комм. ad635e8, 23 мая 2018 г.)

pack-objects: изменить порядок членов, чтобы уменьшить struct object_entry

Предыдущие патчи оставляют много дыр и отступов в этой структуре.
Этот патч переупорядочивает члены и сокращает структуру до 80 байтов (от 136 байтов в 64-битных системах до того, как будет выполнено какое-либо сжатие полей) с резервированием 16 битов (и еще парой в in_pack_header_size, когда у нас действительно заканчиваются биты),

Это последнее из серии исправлений сокращения памяти (см. " Pack-objects: немного документа о struct object_entry " для первого).

В целом они сократили объем памяти linux-2.6.git с 3,747 г до 3,424 г, или примерно на 320 млн, снижение на 8,5%.
Время выполнения repack осталось неизменным на протяжении всей этой серии.
Тест Овара на большом монорепо, к которому он имеет доступ (больше, чем linux-2.6.git) показал снижение на 7,9%, поэтому общее ожидаемое улучшение должно составить где-то около 8%.


С Git 2.20 (Q4 2018) будет проще проверить, не существует ли объект, существующий в одном форке, как дельта против другого объекта, который не появляется в том же разветвленном хранилище.

Смотрите коммит fe0ac2f, коммит 108f530, коммит f64ba53 (16 августа 2018 г.) Кристиана Кудера ( chriscool )
Помогает: Джефф Кинг ( peff ) и Дуй Нгуен ( pclouds )
См. Коммит 9eb0986, коммит 16d75fa, коммит 28b8a73, коммит c8d521f (16 августа 2018 г.) Джеффа Кинга ( peff )
Помогает: Джефф Кинг ( peff ) и Дуй Нгуен ( pclouds )
(Объединено Юнио С Хамано - gitster - в комитете f3504ea, 17 сентября 2018 г.)

pack-objects: переехать ' layer в struct packing_data '

Это уменьшает размер struct object_entry с 88 байт до 80 и, следовательно, повышает эффективность упаковки объектов.

Например, в репозитории Linux с 12M объектами, git pack-objects --all требуется дополнительная память 96 МБ, даже если функция слоя не используется.

Вы можете использовать атрибут offta delta, чтобы отключить дельта-сжатие только для двоичных объектов этих путей:

В foo/.git/info/attributes (или же foo.git/info/attributes если это пустой репозиторий) (смотрите дельта-запись в gitattributes и смотрите gitignore для синтаксиса шаблона):

/large_file_dir/* -delta
*.psd -delta
/data/*.iso -delta
/some/big/file -delta
another/file/that/is/large -delta

Это не повлияет на клоны хранилища. Чтобы повлиять на другие репозитории (например, клоны), поместите атрибуты в .gitattributes файл вместо (или в дополнение к) info/attributes файл.

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