Başkalarının da belirttiği gibi, Haskell otomatik , dinamik bellek yönetimi gerektirir : otomatik bellek yönetimi gereklidir çünkü manuel bellek yönetimi güvensizdir; dinamik bellek yönetimi gereklidir çünkü bazı programlar için bir nesnenin ömrü yalnızca çalışma zamanında belirlenebilir.
Örneğin, aşağıdaki programı düşünün:
main = loop (Just [1..1000]) where
loop :: Maybe [Int] -> IO ()
loop obj = do
print obj
resp <- getLine
if resp == "clear"
then loop Nothing
else loop obj
Bu programda liste [1..1000]
, kullanıcı "temizle" yazana kadar bellekte tutulmalıdır; bu nedenle bu yaşam boyu olmalıdır dinamik belirlenecek ve dinamik bellek yönetimi neden gerekli olduğunu budur.
Dolayısıyla bu anlamda, otomatik dinamik bellek tahsisi gereklidir ve pratikte bunun anlamı: evet , Haskell bir çöp toplayıcı gerektirir, çünkü çöp toplama en yüksek performanslı otomatik dinamik bellek yöneticisidir.
Ancak...
Bir çöp toplayıcı gerekli olsa da, derleyicinin çöp toplamadan daha ucuz bir bellek yönetimi şeması kullanabileceği bazı özel durumlar bulmaya çalışabiliriz. Örneğin, verilen
f :: Integer -> Integer
f x = let x2 = x*x in x2*x2
Derleyicinin x2
, f
geri döndüğünde (çöp toplayıcının serbest bırakmasını beklemek yerine) güvenli bir şekilde ayrılabileceğini algılamasını umabiliriz x2
. Esasen, derleyicinin ayırmaları çöpte toplanan yığına, mümkün olduğunda yığın üzerindeki ayırmalara dönüştürmek için kaçış analizi gerçekleştirmesini istiyoruz.
Bunu istemek çok mantıksız değildir: jhc haskell derleyicisi bunu yapar, ancak GHC yapmaz. Simon Marlow , GHC'nin nesilsel çöp toplayıcısının kaçış analizini çoğunlukla gereksiz hale getirdiğini söylüyor .
jhc aslında bölge çıkarımı olarak bilinen sofistike bir kaçış analizi kullanır . Düşünmek
f :: Integer -> (Integer, Integer)
f x = let x2 = x * x in (x2, x2+1)
g :: Integer -> Integer
g x = case f x of (y, z) -> y + z
Bu durumda, basit bir kaçış analizi, x2
kaçışların f
(demet içinde döndürüldüğü için) olduğu sonucuna varır ve bu nedenle x2
çöp toplama yığınına tahsis edilmesi gerekir. Öte yandan bölge çıkarımı, geri döndüğünde x2
ayrılabilecek olanı tespit edebilir g
; buradaki fikir, bunun bölgesinden ziyade bölgesine x2
tahsis edilmesi gerektiğidir .g
f
Haskell'in ötesinde
Yukarıda tartışıldığı gibi bazı durumlarda bölge çıkarımı yararlı olsa da, tembel değerlendirmeyle etkili bir şekilde uzlaştırmak zor görünmektedir ( Edward Kmett ve Simon Peyton Jones'un yorumlarına bakınız). Örneğin, düşünün
f :: Integer -> Integer
f n = product [1..n]
Listeyi [1..n]
yığına ayırmak ve f
geri döndükten sonra onu serbest bırakmak cazip gelebilir , ancak bu felaket olur: f
O (1) belleğini (çöp toplama altında) kullanmaktan O (n) belleğine değişir .
Katı işlevsel dil ML'si için bölge çıkarımı konusunda 1990'larda ve 2000'lerin başında kapsamlı çalışmalar yapıldı . Mads Tofte, Lars Birkedal, Martin Elsman, Niels Hallenberg , çoğu MLKit derleyicisine entegre ettikleri bölge çıkarımı konusundaki çalışmaları üzerine oldukça okunabilir bir geriye dönük yazmışlardır . Tamamen bölge tabanlı bellek yönetimi (yani çöp toplayıcı yok) ve ayrıca hibrit bölge tabanlı / çöp toplanan bellek yönetimi ile deneyler yaptılar ve test programlarının saf çöpten "10 kat daha hızlı ve 4 kat daha yavaş" çalıştığını bildirdi. toplanan sürümler.