我正在共享主机上托管git repo。我的repo必然有几个非常大的文件,每次我尝试在repo上运行“git gc”时,我的进程被共享主机提供程序杀死,因为使用了太多内存。有没有办法限制git gc可以消耗的内存量?我希望它能够以更快的速度交换内存使用,并且需要更长的时间来完成它的工作。
答案 0 :(得分:33)
我使用了此link的说明。与Charles Baileys建议的想法相同。
命令的副本在这里:
git config --global pack.windowMemory "100m"
git config --global pack.packSizeLimit "100m"
git config --global pack.threads "1"
这对我在hostgator上使用共享主机帐户。
答案 1 :(得分:15)
是的,请查看git config
的帮助页面并查看pack.*
选项,特别是pack.depth
,pack.window
,pack.windowMemory
和{{ 1}}。
这不是一个完全确切的大小,因为git需要将每个对象映射到内存中,因此无论窗口和增量缓存设置如何,一个非常大的对象都会导致大量内存使用。
您可以更好地在本地打包并“手动”将包文件传输到远程端,添加pack.deltaCacheSize
个文件,以便远程git不会尝试完全重新包装所有内容。
答案 2 :(得分:10)
Git repack的内存使用是:(pack.deltaCacheSize + pack.windowMemory) × pack.threads
。相应的默认值为256MiB,无限制,nproc。
delta缓存没用:大部分时间都花在计算滑动窗口的增量上,其中大部分被丢弃;缓存幸存者,这样他们可以重复使用一次(写作时)不会改善运行时。线程之间也不共享该缓存。
默认情况下,窗口内存限制为pack.window
(gc.aggressiveWindow
)。以这种方式限制包装是一个坏主意,因为工作集的大小和效率会有很大差异。最好将两者都提高到更高的值,并依靠pack.windowMemory
来限制窗口大小。
最后,线程的缺点是拆分工作集。降低pack.threads
并增加pack.windowMemory
以使总数保持不变可以改善运行时间。
repack还有其他有用的可调参数(pack.depth
,pack.compression
,位图选项),但它们不会影响内存使用。
答案 3 :(得分:7)
您可以使用关闭delta属性来仅为这些路径名的blob禁用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
文件中(或除此之外)。
答案 4 :(得分:1)
Git 2.18(2018年第二季度)将改善gc内存消耗
在2.18之前,“git pack-objects
”需要在执行其工作时分配大量“struct object_entry
”:缩小其大小有助于提高性能
相当多
这会影响git gc
。
请参阅commit f6a5576,commit 3b13a5f,commit 0aca34e,commit ac77d0c,commit 27a7d06,commit 660b373,commit 0cb3c14,{{3} },commit 898eba5,commit 43fa44f,commit 06af3bb,commit b5c0cbd,commit 0c6804a,commit fd9b1ba,commit 8d6ccce(2018年4月14日){ {3}}。
(由commit 4c2db93合并于Nguyễn Thái Ngọc Duy (pclouds
),2018年5月23日)
pack-objects
:重新排序成员以缩小struct object_entry
以前的补丁会在此结构中留下大量漏洞和填充 此修补程序重新排序成员并将结构缩小到80个字节 (在64位系统上从136字节开始,在完成任何字段缩小之前) 有16位备用(和in_pack_header_size时多一些) 我们真的没用了。)
这是一系列内存减少补丁中的最后一个(参见 “Junio C Hamano --
gitster
--” 第一个)。总的来说,他们减少了
linux-2.6.git
上的重新包装内存大小 3.747G至3.424G,或约320M,减少8.5% 重新包装的运行时间在整个系列中保持不变 Ævar对他可以访问的大型monorepo(大于linux-2.6.git
)的测试显示减少了7.9%,因此整体预期的改进应该是 大约8%左右。
使用Git 2.20(Q8 2018),可以更容易地检查一个fork中存在的对象是否与另一个未出现在同一分叉存储库中的对象形成delta。
commit ad635e8见pack-objects: a bit of document about struct object_entry,commit fe0ac2f,commit 108f530(2018年8月16日)。
帮助:commit f64ba53和Christian Couder (chriscool
)
Jeff King (peff
)见Duy Nguyen (pclouds
),commit 9eb0986,commit 16d75fa,commit 28b8a73(2018年8月16日)。
帮助:commit c8d521f和Jeff King (peff
)
(由Jeff King (peff
)合并于Duy Nguyen (pclouds
),2018年9月17日)
pack-objects
:将“layer
”移动到“struct packing_data
”这会将'struct object_entry'的大小从88个字节减少到80个,从而使打包对象更有效。
例如,在具有12M对象的Linux存储库上,即使未使用图层功能,
git pack-objects --all
也需要额外的96MB内存。
请注意,Git 2.21(2019年2月)修复了一个小错误:“git pack-objects”错误地使用了未初始化的互斥锁,该错误已被更正。
Junio C Hamano -- gitster
--见commit f3504ea,commit edb673c(2019年1月25日)
帮助:commit 459307b。
(Patrick Hogg (``)合并于Junio C Hamano (gitster
),2019年2月5日)
pack-objects
:将read mutex移动到packing_data
structJunio C Hamano --
gitster
--(“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年2月)仍然找到另一种方法,用“git pack-objects
”学习另一种算法来计算包的大小
要发送的对象,将生成的packfile交换为保存
横向成本支持小推动。
pack-objects
:创建pack.useSparse
设置“
--sparse
”中的“git pack-objects
”标志会更改算法 用于枚举对象更快的个人对象 用户推送只改变小锥体的新对象 工作目录 建议不要为服务器使用稀疏算法,因为服务器可能会发送出现在整个工作目录中的新对象。创建一个启用此新算法的“
pack.useSparse
”设置 这允许'git push
'使用此算法而不传递 '--sparse
'一直标记run_command()
的四个级别 调用如果设置了“
--no-sparse
”标志,则此配置设置为 重写的。
commit d243a32现在包括:
pack.useSparse:
如果为true,Git将默认使用“
--sparse
”选项 当“git pack-objects
”选项存在时,“--revs
” 这个 算法仅处理出现在引入新路径的路径中的树 对象。这可以带来显着的性能优势 计算一个包发送一个小的变化。
然而,这是可能的 如果包含,则将额外的对象添加到包文件中 提交包含某些类型的直接重命名。
有关具体说明,请参阅“ac77d0c”。