内存管理和垃圾回收
Julia通过其内置的垃圾收集器(GC)使用自动内存管理。 本节概述Julia如何管理内存,以及如何配置和优化应用程序的内存使用情况。
垃圾回收概述
Julia具有以下特征的垃圾收集器:
**不可移动*:垃圾回收期间对象不会在内存中重新定位 **世代*:较年轻的对象比较旧的对象更频繁地收集 **并行和部分并发*:GC可以使用多个线程并与您的程序并发运行 **Mostly precise*:GC准确识别纯Julia代码的对象引用,并为从C调用Julia的用户提供保守的扫描Api
垃圾回收器会自动回收程序无法访问的对象所使用的内存,在大多数情况下,您可以从手动内存管理中解脱出来。
内存架构
Julia使用两层分配策略:
**小对象*(当前≤2032字节,但可能会更改):使用快速每线程池分配器分配
**大型对象*:直接通过系统的 马洛克
这种混合方法优化了分配速度和内存效率,池分配器为Julia程序中典型的许多小对象提供了快速分配。
系统内存要求
交换空间
Julia的垃圾收集器的设计期望您的系统配置了足够的交换空间。 GC使用启发式方法,假设它可以在需要时分配超出物理RAM的内存,依赖于操作系统的虚拟内存管理。
如果您的系统交换空间有限或没有交换空间,则在垃圾回收期间可能会遇到内存不足错误。 在这种情况下,您可以使用 --堆大小提示 限制Julia内存使用的选项。
记忆提示
您可以向Julia提供有关要使用的最大内存量的提示:
julia --heap-size-hint=4G # To set the hint to ~4GB
julia --heap-size-hint=50% # or to 50% of physical memory
该 --堆大小提示 option告诉垃圾收集器在接近指定限制时更积极地触发收集。 这在以下方面特别有用:
*具有内存限制的容器 *没有交换空间的系统 *要限制Julia内存占用的共享系统
您也可以通过 JULIA_HEAP_SIZE_HINT 环境变量:
export JULIA_HEAP_SIZE_HINT=2G
julia
多线程垃圾回收
Julia的垃圾回收器可以利用多个线程来提高多核系统的性能。
GC线程配置
默认情况下,Julia使用多个线程进行垃圾回收:
**标记线程*:在标记阶段用于跟踪对象引用(默认值:1,如果只有一个,则与计算线程共享,否则为计算线程数的一半) **扫描线程*:用于并发扫描释放的内存(默认:0,禁用)
您可以使用以下方法配置GC线程:
julia --gcthreads=4,1 # 4 mark threads, 1 sweep thread
julia --gcthreads=8 # 8 mark threads, 0 sweep threads
或通过环境变量:
export JULIA_NUM_GC_THREADS=4,1
julia
监控和调试
性能考虑因素
减少拨款
最小化GC影响的最佳方法是减少不必要的分配:
*尽可能使用就地操作(例如, x.+=y 而不是 x=x+y)
*预先分配数组并重用它们
*避免在紧密循环中创建临时对象
*考虑使用 StaticArrays。jl 对于小型、固定大小的阵列
分析内存使用情况
有关分析内存分配和识别性能瓶颈的详细指南,请参阅 剖析部分。