Я размещаю репозиторий git на общем хосте. В моем репозитории обязательно есть пара очень больших файлов, и каждый раз, когда я сейчас пытаюсь запустить «git gc» в репозитории, мой процесс уничтожается поставщиком общего хостинга за использование слишком большого объема памяти. Есть ли способ ограничить объем памяти, который может потреблять git gc? Я надеюсь, что он сможет обменять использование памяти на скорость и просто займет немного больше времени, чтобы выполнить свою работу.
Есть ли способ ограничить объем памяти, который использует git gc?
Ответы (5)
Да, взгляните на страницу справки для git config
и посмотрите на параметры pack.*
, в частности, pack.depth
, pack.window
, pack.windowMemory
и pack.deltaCacheSize
.
Это не совсем точный размер, так как git необходимо отображать каждый объект в памяти, поэтому один очень большой объект может привести к большому использованию памяти независимо от настроек окна и дельта-кэша.
Возможно, вам больше повезет, если вы упаковываете локально и передаете файлы пакета на удаленную сторону «вручную», добавляя файлы .keep
, чтобы удаленный git никогда не пытался полностью перепаковать все.
Я использовал инструкции по этой ссылке< /а>. Та же идея, что предложил Charles Baileys.
Копия команд здесь:
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
, параметры растрового изображения), но они не влияют на использование памяти.
Вы можете отключить дельта-атрибут, чтобы отключить дельта-сжатие только для больших двоичных объектов с этими путями:
В 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
(или в дополнение к нему).
Git 2.18 (второй квартал 2018 г.) улучшит потребление памяти gc.
До версии 2.18 " git pack-objects
" должен выделять массу "struct object_entry
" при выполнении своей работы: уменьшение его размера немного повышает производительность.
Это влияет на git gc
.
См. commit f6a5576, коммит 3b13a5f, , коммит ac77d0c, коммит 27a7d06, зафиксировать 660b373, зафиксировать 0cb3c14, зафиксировать 898eba5, зафиксировать 43fa44f , коммит 06af3bb, коммит b5c0cbd, , коммит fd9b1ba, зафиксировать 8d6ccce, коммит 4c2db93 (14 апреля 2018 г.), автор Нгуен Тай Нгок Зуй (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 %.
Время выполнения перепаковки не изменилось на протяжении всей этой серии.
Эвар тестирует на большой монорепозиторий, к которому у него есть доступ (больше, чемlinux-2.6.git
), показал снижение на 7,9%, поэтому общее ожидаемое улучшение должно составить где-то около 8%.
В Git 2.20 (четвертый квартал 2018 г.) будет проще проверять объект, который существует в одном ответвлении, не превращается в дельту по сравнению с другим объектом, который не появляется в том же ответвленном репозитории.
См. коммит fe0ac2f, коммит 108f530, Christian Couder (chriscool
).
Помощь: Джефф Кинг (peff
) и Дуй Нгуен (pclouds
).
См. commit 9eb0986, коммит 16d75fa, коммит 28b8a73, noreferrer18b8a73 a> (16 августа 2018 г.), Джефф Кинг (peff
).
Помощь: Джефф Кинг (peff
) и Duy Nguyen (pclouds
).
(Объединено Junio C Hamano -- gitster
- – в commit f3504ea, 17 сентября 2018 г.)
pack-objects
: переместите 'layer
' в 'struct packing_data
'Это уменьшает размер struct object_entry с 88 байт до 80 и, следовательно, делает упаковку объектов более эффективной.
Например, в репозитории Linux с 12 миллионами объектов
git pack-objects --all
требуется дополнительная память на 96 МБ, даже если функция слоя не используется.
Обратите внимание, что Git 2.21 (февраль 2019 г.) исправляет небольшую ошибку: «git pack-objects
» неправильно использовал неинициализированный мьютекс, который был исправлен.
См. коммит edb673c, коммит 459307b (25 января 2019 г.), автор Патрик Хогг ( ``).
Помощь: Юнио С Хамано (gitster
).
(Объединено Junio C Hamano -- gitster
-- в commit d243a32, 5 февраля 2019 г.)
pack-objects
: переместить мьютекс чтения в структуруpacking_data
ac77d0c ("
pack-objects
: уменьшить поле размера в структуреobject_entry
", 2018-04-14 ) добавлено дополнительное использование read_lock/read_unlock в недавно представленномoe_get_size_slow
для безопасности потоков при параллельных вызовахtry_delta()
.
К сожалению,oe_get_size_slow
также используется в последовательном коде, некоторые из которых вызываются перед первым вызовомll_find_deltas
.
Таким образом, инициализация мьютекса чтения не гарантируется.Решите эту проблему, переместив мьютекс чтения в
packing_data
и инициализировав его в prepare_packing_data, который инициализируется вcmd_pack_objects
.
Git 2.21 (февраль 2019 г.) по-прежнему находит другой способ уменьшить размер пакета с помощью «git pack-objects
», изучающего другой алгоритм для вычисления набора объектов для отправки, который обменивает полученный пакетный файл, чтобы сэкономить затраты на обход в пользу небольших толчков.
pack-objects
: создать настройкуpack.useSparse
Флаг '
--sparse
' в 'git pack-objects
' изменяет алгоритм, используемый для перечисления объектов, на более быстрый для отдельных пользователей, добавляющих новые объекты, которые изменяют только небольшой конус рабочего каталога.
Разреженный алгоритм не рекомендуется для сервера. , который, вероятно, отправляет новые объекты, которые появляются во всем рабочем каталоге.Создайте параметр "
pack.useSparse
", который включает этот новый алгоритм.
Это позволит "git push
" использовать этот алгоритм без передачи флага "--sparse
" на всех четырех уровнях вызововrun_command()
.Если установлен флаг «
--no-sparse
», этот параметр конфигурации переопределяется.
документация пакета конфигурации теперь включает :
pack.useSparse:
Если задано значение true, Git по умолчанию будет использовать параметр "
--sparse
" в параметре "git pack-objects
", если присутствует параметр "--revs
".
Этот алгоритм обходит только деревья, которые появляются на путях, вводящих новые объекты.Это может дать значительный выигрыш в производительности при вычислении пакета для отправки небольшого сдачи.
Однако возможно, что в пакетный файл будут добавлены дополнительные объекты, если включенные коммиты содержат определенные типы прямых переименований.
Конкретную иллюстрацию см. в разделе "git push
работает очень медленно для огромного репо".
Примечание: как было сказано в Git 2.24, такая настройка, как pack.useSparse
, все еще является экспериментальной.
См. коммит aaf633c, коммит c6cc4c5, Деррик Столи (derrickstolee
).
(Объединено Junio C Hamano -- gitster
-- в commit f4f8dfe, 9 сентября 2019 г.)< / суп>
repo-settings
: создать настройкуfeature.experimental
Параметр "
feature.experimental
" включает параметры конфигурации, которые не должны стать значениями по умолчанию, но требуют дополнительного тестированияg.Обновите следующие параметры конфигурации, чтобы принять новые значения по умолчанию и использовать структуру
repo_settings
, если она еще не используется:
- 'pack.useSparse=истина'
- 'fetch.negotiationAlgorithm=пропуск'
В Git 2.26 (1 квартал 2020 г.) метод «git pack-objects
» повторно использует сохраненные объекты. в существующем пакете для генерации его результата было улучшено.
См. commit d2ea031, зафиксировать 92fb0db, Джефф Кинг (peff
).< br> (Объединено Junio C Hamano -- gitster
-- в commit a14aebe, 14 февраля 2020 г.)
pack-objects
: улучшение частичного повторного использования файла пакета.При содействии: Джонатан Тан
Подпись: Джефф Кинг
Подпись: Кристиан КудерСтарый код для повторного использования дельт из существующего файла пакета просто пытался дословно вывести весь сегмент пакета. Это быстрее, чем традиционный способ добавления объектов в упаковочный лист, но срабатывает не так часто. Этот новый код действительно предлагает золотую середину: выполнять некоторую работу с каждым объектом, но гораздо меньше, чем мы обычно делаем.
Общая стратегия нового кода состоит в том, чтобы создать растровое изображение объектов из файла пакета, который мы включим, а затем перебрать его, записывая каждый объект точно так, как он находится в нашем пакете на диске, но не em> добавление его в наш список пакетов (что требует памяти и увеличивает пространство для поиска дельт).
Одна сложность заключается в том, что если мы опускаем некоторые объекты, мы не можем установить дельту для базы, которую мы не отправляем. Итак, мы должны проверить каждый объект в
try_partial_reuse()
, чтобы убедиться, что у нас есть его дельта.Что касается производительности, в худшем случае у нас может быть чередование объектов, которые мы отправляем или не отправляем, и у нас будет столько же фрагментов, сколько и объектов. Но на практике мы отправляем большие куски.
Например, при упаковке torvalds/linux на серверах GitHub теперь повторно использовалось 6,5 млн объектов, но требовалось всего около 50 тыс. фрагментов.
git
убивали, ноdarcs
(другая система контроля версий) всегда убивалась, поэтому ее невозможно использовать на Dreamhost.com - person imz -- Ivan Zakharyaschev   schedule 25.02.2015