Lidar com o e minimizando, uso de memória em Common Lisp (SBCL)
-
22-08-2019 - |
Pergunta
Eu tenho um VPS com não muito de memória (256 MB) que eu estou tentando usar para o desenvolvimento Lisp comum com SBCL + Hunchentoot para escrever algumas aplicações web simples. Uma grande quantidade de memória parece estar se acostumando sem fazer nada particularmente complexa, e depois de um tempo de servir páginas que fique sem memória e quer enlouquece usando toda swap ou (se não houver troca) apenas morre.
Então, eu preciso de ajuda para:
- Descubra o que está usando toda a memória (se é bibliotecas ou me, especialmente)
- limite a quantidade de memória que SBCL é permitida a utilização, para evitar enormes quantidades de trocar
- coisas Handle limpa quando a memória se esgota, em vez de deixar de funcionar (já que é um web-app eu quero continuar e tentar limpar).
Eu assumo os dois primeiros são razoavelmente simples, mas é o terceiro mesmo possível? Como as pessoas lidam com out-of-memory ou constrangidos condições de memória em Lisp?
(Além disso, faço notar que a 64-bit SBCL parece usar literalmente o dobro da memória como de 32 bits. É este esperado? Eu posso executar uma versão de 32-bit se ele vai guardar um monte de memória)
Solução
Para limitar o uso de memória do SBCL, use opção de espaço de tamanho --dynamic (por exemplo, sbcl --dynamic-space-size 128
vai limitar o uso de memória de 128M).
Para descobrir quem está usando a memória, você pode chamar (room)
(a função que diz o quanto de memória está sendo usado) em momentos diferentes: na inicialização, depois de todas as bibliotecas são carregados e, em seguida, durante o trabalho (de cource, chamada (sb-ext:gc :full t)
antes quarto para não medir o lixo que ainda não foi recolhida).
Além disso, é possível usar SBCL Profiler para alocação de memória medida.
Outras dicas
Saiba o que está usando toda a memória (Se é bibliotecas ou me, especialmente)
Attila Lendvai tem algum código específico do SBCL para descobrir onde um objetos alocados vem. Consulte http://article.gmane.org/gmane.lisp. steel-bank.devel / 12903 e escrever-lhe um e-mail privado, se necessário.
Não deixe de experimentar outra implementação, de preferência com um GC precisa (como Clozure CL) para garantir que ele não é um vazamento de aplicação específica.
Limitar a quantidade de memória que SBCL é permitido o uso, para evitar maciça quantidades de troca
Já respondeu por outros.
lidar com as coisas de forma limpa quando é executado de memória para fora, em vez de deixar de funcionar (já que é um web-app eu quero continuar e tentar limpar).
256 MB é apertado, mas de qualquer maneira: Programação de um recorrente (talvez 1s) Rosca cronometrado que verifica o espaço livre restante. Se o espaço livre é menor que X, em seguida, usar exec () para substituir a imagem do processo SBCL atual com um novo.
Se você não tem nenhum declarações de tipo, eu esperaria 64-bit Lisp para tomar duas vezes no espaço de um 32-bit um. Mesmo um simples (pequeno) int vai usar um pedaço de memória de 64 bits. Eu não acho que ele vai usar menos do que uma palavra de máquina, a menos que você declará-lo.
Eu não posso ajudar com # 2 e # 3, mas se você descobrir o # 1, eu suspeito que não será um problema. Já vi casos SBCL / Hunchentoot correndo por eras. Se eu estou usando uma quantidade exorbitante de memória, geralmente é culpa minha. : -)
Eu não seria surpreendido por uma 64-bit SBCL usando o dobro da meory, como provavelmente vai usar uma célula de 64 bits em vez de um 32-bit um, mas não poderia dizer com certeza sem realmente verificar.
coisas típicas que mantêm a memória pendurado em torno de mais tempo do que o esperado são referências não são mais úteis que ainda têm um caminho para o conjunto de alocação de raiz (tabelas hash estão, eu acho, uma boa maneira de deixar essas coisas Linger). Você poderia tentar intercalando chamadas explícitas para GC em seu código e certifique-se (tanto quanto possível) não guardar as coisas em variáveis ??globais.