J'ai découvert une fuite de mémoire dans mon Rails de code, c'est-à-dire, j'ai trouvé ce code fuites, mais pas pourquoi il ya des fuites. Je l'ai réduite à un cas de test qui ne nécessite pas de Rails:
require 'csspool'
require 'ruby-mass'
def report
puts 'Memory ' + `ps ax -o pid,rss | grep -E "^[[:space:]]*#{$$}"`.strip.split.map(&:to_i)[1].to_s + 'KB'
Mass.print
end
report
# note I do not store the return value here
CSSPool::CSS::Document.parse(File.new('/home/jason/big.css'))
ObjectSpace.garbage_collect
sleep 1
report
ruby-masse soi-disant me permet de voir tous les objets en mémoire. CSSPool est un CSS analyseur basé sur racc. /home/jason/big.css est un 1.5 MO fichier CSS.
Ce sorties:
Memory 9264KB
==================================================
Objects within [] namespace
==================================================
String: 7261
RubyVM::InstructionSequence: 1151
Array: 562
Class: 313
Regexp: 181
Proc: 111
Encoding: 99
Gem::StubSpecification: 66
Gem::StubSpecification::StubLine: 60
Gem::Version: 60
Module: 31
Hash: 29
Gem::Requirement: 25
RubyVM::Env: 11
Gem::Specification: 8
Float: 7
Gem::Dependency: 7
Range: 4
Bignum: 3
IO: 3
Mutex: 3
Time: 3
Object: 2
ARGF.class: 1
Binding: 1
Complex: 1
Data: 1
Gem::PathSupport: 1
IOError: 1
MatchData: 1
Monitor: 1
NoMemoryError: 1
Process::Status: 1
Random: 1
RubyVM: 1
SystemStackError: 1
Thread: 1
ThreadGroup: 1
fatal: 1
==================================================
Memory 258860KB
==================================================
Objects within [] namespace
==================================================
String: 7456
RubyVM::InstructionSequence: 1151
Array: 564
Class: 313
Regexp: 181
Proc: 113
Encoding: 99
Gem::StubSpecification: 66
Gem::StubSpecification::StubLine: 60
Gem::Version: 60
Module: 31
Hash: 30
Gem::Requirement: 25
RubyVM::Env: 13
Gem::Specification: 8
Float: 7
Gem::Dependency: 7
Range: 4
Bignum: 3
IO: 3
Mutex: 3
Time: 3
Object: 2
ARGF.class: 1
Binding: 1
Complex: 1
Data: 1
Gem::PathSupport: 1
IOError: 1
MatchData: 1
Monitor: 1
NoMemoryError: 1
Process::Status: 1
Random: 1
RubyVM: 1
SystemStackError: 1
Thread: 1
ThreadGroup: 1
fatal: 1
==================================================
Vous pouvez voir le mémoire va moyen . Certains des compteurs, mais pas d'objets spécifiques à CSSPool sont présents. J'ai utilisé ruby-masse "index" méthode pour inspecter les objets qui ont des références comme suit:
Mass.index.each do |k,v|
v.each do |id|
refs = Mass.references(Mass[id])
puts refs if !refs.empty?
end
end
Mais encore une fois, cela ne me donne pas tout ce qui est lié à CSSPool, juste gem info et autres.
J'ai aussi essayé de la sortie "GC.stat"...
puts GC.stat
CSSPool::CSS::Document.parse(File.new('/home/jason/big.css'))
ObjectSpace.garbage_collect
sleep 1
puts GC.stat
Résultat:
{:count=>4, :heap_used=>126, :heap_length=>138, :heap_increment=>12, :heap_live_num=>50924, :heap_free_num=>24595, :heap_final_num=>0, :total_allocated_object=>86030, :total_freed_object=>35106}
{:count=>16, :heap_used=>6039, :heap_length=>12933, :heap_increment=>3841, :heap_live_num=>13369, :heap_free_num=>2443302, :heap_final_num=>0, :total_allocated_object=>3771675, :total_freed_object=>3758306}
Si je comprends bien, si un objet n'est pas référencée et la collecte des ordures se passe, alors que l'objet doit être effacé de la mémoire. Mais cela ne semble pas être ce qui se passe ici.
J'ai aussi lu sur le C-niveau de fuites de mémoire, et depuis CSSPool utilise Racc qui utilise le code en C, je pense que c'est une possibilité. J'ai couru mon code par Valgrind:
valgrind --partial-loads-ok=yes --undef-value-errors=no --leak-check=full --fullpath-after= ruby leak.rb 2> valgrind.txt
Les résultats sont ici. Je ne suis pas sûr si cela se confirme C au niveau de la fuite, comme je l'ai également lu que Ruby fait les choses avec la mémoire que Valgrind ne pas comprendre.
Les Versions utilisées:
- Ruby 2.0.0-p247 (c'est ce que mon application Rails pistes)
- Ruby 1.9.3-p392-ref (pour les tests avec ruby-masse)
- ruby-masse 0.1.3
- CSSPool 4.0.0 à partir d' ici
- CentOS 6.4 et Ubuntu 13.10