Есть ли способ ограничить объем памяти, который использует "git gc"? - PullRequest
29 голосов
/ 22 июня 2010

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

Ответы [ 5 ]

34 голосов
/ 06 января 2012

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

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

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

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

15 голосов
/ 22 июня 2010

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

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

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

10 голосов
/ 08 января 2015

Использование памяти 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, параметры растрового изображения), но они не влияют на использование памяти.

7 голосов
/ 23 июня 2010

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

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

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

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

1 голос
/ 26 мая 2018

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

См. коммит f6a5576 , коммит 3b13a5f , коммит 0aca34e , commit ac77d0c , commit 27a7d06 , commit 660b373 , commit 0cb3c14 , commit 898eba5 , commit43fa44f , commit 06af3bb , commit b5c0cbd , commit 0c6804a , commit fd9b1ba , commit 8d6ccce , коммит 4c2db93 (14 апреля 2018 г.) от Нгуен Тай Нгок Дуй (pclouds) .
(объединено Junio ​​C Hamano - gitster- in commit 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%.
Время выполнения перепаковки во всех сериях не изменилось.
Испытание Эвара на большом монорепо, к которому он имеет доступ (больше linux-2.6.git), показало снижение на 7,9%, поэтому общее ожидаемое улучшение должно составить где-то около 8%.


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

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

pack-objects: переместить 'layer' в 'struct packing_data'

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

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


Обратите внимание, что Git 2.21 (февраль.2019) исправляет небольшую ошибку: «git pack-objects» неправильно использовал неинициализированный мьютекс, который был исправлен.

См. commit edb673c , commit 459307b (25 января2019) Патрик Хогг (``) .
Помощник: Хунио С. Хамано (gitster) .
(Объединено Junio ​​C Hamano - gitster - in commit d243a32 , 05 февраля 2019 г.)

pack-objects: переместить мьютекс чтения в packing_datastruct

ac77d0c ("pack-objects: поле уменьшенного размера в struct object_entry", 2018-04-14) добавлено дополнительное использование read_lock / read_unlock во вновь представленной oe_get_size_slow для обеспечения безопасности потоков при параллельных вызовах try_delta().
К сожалению, oe_get_size_slow также используется в последовательном коде, некоторые из которых вызываются до первого вызова ll_find_deltas.
Как таковой, мьютекс чтения не являетсягарантированно будет инициализирован.

Решите это, переместив мьютекс чтения в packing_data и инициализировав его.n prepare_packing_data, который инициализируется в cmd_pack_objects.


Git 2.21 (февраль 2019), все еще находит другой способ уменьшить размер пакета с помощью "git pack-objects", изучая другой алгоритм длявычислить набор отправляемых объектов, который обменивает полученный пакетный файл, чтобы сэкономить на стоимости обхода и использовать небольшие толчки.

pack-objects: создать pack.useSparse параметр

The '--sparse 'flag in' git pack-objects 'изменяет алгоритм, используемый для перечисления объектов, на алгоритм, более быстрый для отдельных пользователей, выдвигающих новые объекты, которые изменяют только небольшой конус рабочего каталога.
Разреженный алгоритм не рекомендуется длясервер, который, вероятно, отправляет новые объекты, которые появляются по всему рабочему каталогу.

Создайте параметр 'pack.useSparse', который включает этот новый алгоритм.
Это позволяет 'git push' использовать этот алгоритм безпрохождение флага '--sparse' через четыре уровня вызовов run_command().

Если установлен флаг '--no-sparse', то этот параметр конфигурации будет переопределен.

Документация пакета конфигурации теперь включает в себя:

pack.useSparse:

Если true, Git по умолчанию использует опцию '--sparse' в'git pack-objects' когда присутствует опция '--revs'.
Этот алгоритм обходит только деревья, которые появляются в путях, которые вводят новые объекты.

Это может значительно повысить производительность при вычислении пакета для отправки небольшого изменения.

Однако возможно добавление дополнительных объектов в файл пакета, если включенные коммиты содержат определенные типы прямых переименований.

См. "git push очень медленно для огромного репо "для конкретной иллюстрации.

...