Web services 在长时间运行的公共Lisp应用程序中,应该使用什么策略来管理垃圾?

Web services 在长时间运行的公共Lisp应用程序中,应该使用什么策略来管理垃圾?,web-services,garbage-collection,lisp,common-lisp,Web Services,Garbage Collection,Lisp,Common Lisp,如果我在公共Lisp映像中托管一个长时间运行的应用程序(如web服务器),我应该使用什么策略来管理垃圾收集器 我假设,在默认情况下,垃圾收集器有权花很长时间整理堆,有时我无法预测。这可能会以我不希望的方式影响特定的浏览器请求 在Common Lisp中是否有一种方法可以控制这种情况?也许是鼓励它以“少而常”的方式工作?从早期开始,垃圾收集已经走了很长的路,为了避免不可预知的长时间等待,已经做了很多工作。对于现代实现,我认为这些已经成为过去 但是,垃圾收集的细节因实现而异。现在没有那么多高质量的L

如果我在公共Lisp映像中托管一个长时间运行的应用程序(如web服务器),我应该使用什么策略来管理垃圾收集器

我假设,在默认情况下,垃圾收集器有权花很长时间整理堆,有时我无法预测。这可能会以我不希望的方式影响特定的浏览器请求


在Common Lisp中是否有一种方法可以控制这种情况?也许是鼓励它以“少而常”的方式工作?

从早期开始,垃圾收集已经走了很长的路,为了避免不可预知的长时间等待,已经做了很多工作。对于现代实现,我认为这些已经成为过去


但是,垃圾收集的细节因实现而异。现在没有那么多高质量的Lisp实现,因此您应该可以很容易地查阅他们关于垃圾收集的文档。

一些Lisp实现具有优秀的垃圾收集器。一个特殊的问题是Lisp应用程序通常具有较高的小对象分配率(conses,…)

有一些事情需要考虑。

  • 精确与保守GC。我不是Lisp的保守GCs(Boehm等)的超级粉丝。保守的地面军事系统的一个问题是,他们找不到所有的垃圾。对于长时间运行的程序来说,这可能是一个问题,并且会导致碎片化和无法回收未使用的内存。精确地面军事系统使用Lisp数据的标记信息,可以识别每个对象的每个数据类型。保守的GCs是为不使用标记数据的编程语言实现而发明的(C++,…)

  • 复制GC,压缩GC。为了解决长时间运行的Lisps中的内存碎片问题,可以使用压缩和本地化对象的GC。当哈希表需要重新刷新时(因为位置改变),有时会出现问题。复制GC可能需要更多内存(因为有一个from和to内存空间)。但当GC将对象从一个内存空间复制到另一个内存空间时,它会自动使其更加紧凑。更高级的GCs(如Lisp机器上的GCs)还可以对对象进行排序,并将相同类型的对象分配到彼此相邻的位置,前提是这样可以加快对对象的访问速度

  • 短暂GC。这意味着有第一个GC阶段专门在主内存中运行,并从内存管理单元获得一些支持,以识别更改的内存区域。扫描主内存比扫描虚拟内存快,并且只扫描更改的内存区域可以进一步减少工作量。当分配了大量对象并很快变成垃圾时,这会导致很短的GC暂停

  • 世代GC。如今的地面军事系统通常是分代的。有不止一代,在几代地面军事系统中幸存下来的物体将升级到更老的一代。通常只有第一代人经常进行GCD

  • 调谐。例如,LispWorks和Allegro CL的地面军事系统有很多调谐旋钮。特别是对于长期运行的应用程序,阅读手册,例如调整代数、代大小和其他内容是有意义的

  • 虚拟内存。虚拟内存上的GC通常非常慢。尽可能避免这种情况-为机器添加更多RAM

  • 手动内存管理。例如,CL-HTTP web服务器使用资源执行一些手动内存管理。这些是预先分配的对象池,可以很快重新初始化。Lisp机器经常使用这个。它们的典型用途是在流的读取缓冲区中。与每次读取操作都创建新字符串不同,使用可重用缓冲区非常有用

  • 堆栈分配。一些常见的Lisp允许对某些数据进行堆栈分配—离开块后会自动释放内存。这假定在离开块时不再引用内存。请参见声明
    动态范围

  • 并发GC。通常的公共Lisp实现都没有并发GC和对并发Lisp线程的支持。有些实现具有并发Lisp线程,但GC将在其工作时停止所有这些线程。如果Lisp实现在JVM上运行,比如ABCL,那么它可能能够使用JVM并发/并行GC

  • 分析内存分配。如果您不确定分配发生在哪里以及GC做了什么,那么需要使用分析信息来了解这一点

如果您的Lisp有一个在主内存中运行的精确的分代GC,那么很难用长时间的暂停来解决问题。例如,Clozure CL(一个免费的公共Lisp实现)在某些平台上有一个非常好的GC实现。您希望避免虚拟内存中的内存碎片和垃圾收集。如有必要,请使用64位Lisp实现和更多主内存

指针:

  • 克洛祖雷公司
  • CMUCL
  • LispWorks
  • 快板
您可以从文档中看到,LispWorks和Allegro CL有许多用于调优GC的旋钮

CommonLisp有几个处理实现环境的函数。(ROOM)是一个概述内存使用情况的函数。(t室)提供了更多细节(此处为LispWorks):


您使用的是哪种lisp实现?当您说“我在假设”时,听起来好像您在尝试进行优化,而没有进行任何分析。您是否看到您的环境中需要解决的具体问题?我正在开始向自己介绍尚未出现的问题。考虑到web服务上使用的GC语言的数量,我认为这是一个基本上已解决的问题。哦,我现在不打算优化任何东西。我只是想知道当问题出现时我的选择是什么,我想你不会的
CL-USER 2 > (room t)
 Generation 0:  Total Size 1823K, Allocated 1090K, Free 725K 
          Segment 2008AAB8: Total Size 507K, Allocated 361K, Free 142K
                    minimum free space 64K, 
                      Awaiting promotion = 0K, sweeps before promotion =10
          Segment 217E7050: Total Size 1315K, Allocated 729K, Free 582K
                    minimum free space 0K, 
                      Awaiting promotion = 0K, sweeps before promotion =2
 Generation 1:  Total Size 1397K, Allocated 513K, Free 871K 
          Segment 20CB9A50: Total Size 68K, Allocated 48K, Free 15K
                    minimum free space 0K, 
                      Awaiting promotion = 0K, sweeps before promotion =4
          Segment 216D7050: Total Size 1088K, Allocated 331K, Free 752K
                    minimum free space 0K, 
                      Awaiting promotion = 0K, sweeps before promotion =4
          Segment 2004E4F8: Total Size 241K, Allocated 133K, Free 103K
                    minimum free space 0K, static
 Generation 2:  Total Size 2884K, Allocated 1290K, Free 1585K 
          Segment 21417050: Total Size 2816K, Allocated 1227K, Free 1584K
                    minimum free space 0K, 
                      Awaiting promotion = 0K, sweeps before promotion =4
          Segment 20DA5DA0: Total Size 68K, Allocated 62K, Free 1K
                    minimum free space 117K, 
                      Awaiting promotion = 0K, sweeps before promotion =4
 Generation 3:  Total Size 19373K, Allocated 19232K, Free 128K 
          Segment 20109A50: Total Size 11968K, Allocated 11963K, Free 0K
                    minimum free space 3K, 
                      Awaiting promotion = 0K, sweeps before promotion =10
          Segment 20DB6E18: Total Size 6528K, Allocated 6396K, Free 128K
                    minimum free space 0K, 
                      Awaiting promotion = 0K, sweeps before promotion =10
          Segment 20CCAAC8: Total Size 876K, Allocated 872K, Free 0K
                    minimum free space 0K, 
                      Awaiting promotion = 0K, sweeps before promotion =10

Total Size 25792K, Allocated 22127K, Free 3310K