class HMalloc
Attributes
deallocated[R]
memory[R]
Public Class Methods
new()
click to toggle source
# File lib/hengine/hmalloc.rb, line 59 def initialize hl << "============== NEW HMALLOC ==============".red @expiration = 15 * 60 # seconds @memory = {} @deallocated = {} end
Public Instance Methods
clean()
click to toggle source
# File lib/hengine/hmalloc.rb, line 145 def clean() #GC.start(full_mark: true, immediate_sweep: true) # Start Gargabe Collection immediately and deletes every unused memory block #Senza l'istruzione sopra la memoria viene liberata gradualmente ad es. # - se ho 100 blocchi di memoria non usati ne vengolo liberati solo 40 per poi liberare la restante parte in un momento successivo # - se invece eseguo GC.start sopra con immediate_sweep: true viene liberata tutta la memoria non usata con effetto immediato to_delete = nil to_delete = @memory.select do |oid, node| node.parentNode == nil and node.updateTimestamp + @expiration <= Time.now.to_i end hl << "[start cleaning]#: ...".hight_cyan to_delete.each do |oid, node| self.dealloc(oid) end end
dealloc(oid, deleteFromParent = true)
click to toggle source
# File lib/hengine/hmalloc.rb, line 113 def dealloc(oid, deleteFromParent = true) return unless oid oid = oid.to_i node = @memory[oid] hl << "WARNING: #{oid} not found".red unless node self.hotLog("ERROR: HMalloc::dealloc(#{oid}): already deallocated") if @deallocated[oid] return unless node hl << "[HMalloc.dealloc]#:".green node.show(oid: oid, margin: 3) node.childNodes.clone.each do |childNode| self.dealloc2(childNode.obj, false) end node.parentNode.childNodes.delete(node) if node.parentNode and deleteFromParent @memory.delete(oid) @deallocated[oid] = true if hsd.value("log4memory") end
dealloc2(obj, deleteFromParent = true)
click to toggle source
# File lib/hengine/hmalloc.rb, line 131 def dealloc2(obj, deleteFromParent = true) return unless obj return self.dealloc(obj.object_id, deleteFromParent) end
get(oid)
click to toggle source
# File lib/hengine/hmalloc.rb, line 109 def get(oid) return self.getNode(oid).obj end
getNode(oid)
click to toggle source
# File lib/hengine/hmalloc.rb, line 99 def getNode(oid) oid = oid.to_i node = @memory[oid] self.hotLog("ERROR: HMalloc::getNode(#{oid}): #{oid} deallocated".red) if @deallocated[oid] return nil unless node node.updateTimestamp = Time.now.to_i self.getNode(node.parentNode.obj.object_id) if node.parentNode # Aggiorna updateTimestamp dei genitori return node end
hotLog(str)
click to toggle source
# File lib/hengine/hmalloc.rb, line 141 def hotLog(str) HHotLogger.append(str, "log4memory") end
malloc(obj, poid = nil)
click to toggle source
poid: parent object id
# File lib/hengine/hmalloc.rb, line 67 def malloc(obj, poid = nil) oid = obj.object_id poid = poid.to_i parentNode = @memory[poid] if poid != 0 hl.<< "WARNING malloc: poid #{poid} not found", "ERROR" if poid != 0 and !parentNode node = HNode.new(obj, parentNode) # Se abilita la seguente istruzione non viene deallocata la memoria #ObjectSpace.define_finalizer(obj, proc {|objectId| hl << "Finalizer of the #{objectId}" }) hl.<< "WARNING: #{oid} already exist".red, "ERROR" if @memory.include?(oid) @memory[oid] = node parentNode.childNodes << node if parentNode hl.<< "[HMalloc.malloc]#: ".yellow, "DEBUG2" hl.<< "WARNING: No parent".red, "ERROR" if poid == 0 node.show(oid: oid, margin: 3) return node end
malloc2(obj, parent = nil)
click to toggle source
# File lib/hengine/hmalloc.rb, line 89 def malloc2(obj, parent = nil) return self.malloc(obj, parent.object_id) end
parentOf(oid)
click to toggle source
# File lib/hengine/hmalloc.rb, line 95 def parentOf(oid) return @memory[oid.to_i].parentNode.obj.object_id if oid end
resetMemory()
click to toggle source
# File lib/hengine/hmalloc.rb, line 136 def resetMemory() hl << "Reset Memory ... 100%".hight_cyan @memory = {} end
show()
click to toggle source
# File lib/hengine/hmalloc.rb, line 163 def show hl.<< "################################################################################################".hight_white, "DEBUG2" hl.<< "# #".hight_white, "DEBUG2" hl.<< "# Tree Hypersonic Memory Leak #".hight_white, "DEBUG2" hl.<< "# #".hight_white, "DEBUG2" hl.<< "################################################################################################".hight_white, "DEBUG2" hl.<< "# #".hight_white, "DEBUG2" hl.<< "# Visualizzazione della memoria ad albero (non compare l'oid dei figli) #".hight_white, "DEBUG2" hl.<< "# #".hight_white, "DEBUG2" hl.<< "# Le seguenti allocazioni di memoria possono essere generate in due modi: #".hight_white, "DEBUG2" hl.<< "# #".hight_white, "DEBUG2" hl.<< "# - By connect: in questo caso la tabella sotto mostra il receiver, il metodo e i parametri #".hight_white, "DEBUG2" hl.<< "# es. tr.connect(:ondblclick, self, 'doubleClick', id: @oid, ...) #".hight_white, "DEBUG2" hl.<< "# #".hight_white, "DEBUG2" hl.<< "# - By malloc: in questo caso la tabella sotto mostra l'oggetto usato #".hight_white, "DEBUG2" hl.<< "# es. @oid = hm().malloc(@modelName.clone, poid).obj.object_id.to_s #".hight_white, "DEBUG2" hl.<< "# #".hight_white, "DEBUG2" hl.<< "# - Le righe in rosso sono quelle senza parent (vericare che ce ne sia solo una) #".hight_white, "DEBUG2" hl.<< "# Se ce sono piu' di una e si vuole capire da dove proviene il metodo alloc genera #".hight_white, "DEBUG2" hl.<< "# un Warning rosso quando si esegue una malloc senza poid #".hight_white, "DEBUG2" hl.<< "# #".hight_white, "DEBUG2" hl.<< "################################################################################################".hight_white, "DEBUG2" memory = @memory.sort_by { |oid, node| node.updateTimestamp } memory.each do |oid, node| node.showTree(oid: oid) unless node.parentNode end return memory end
showAll(sorted: false)
click to toggle source
# File lib/hengine/hmalloc.rb, line 196 def showAll(sorted: false) hl.<< "################################################################################################".hight_white, "DEBUG2" hl.<< "# #".hight_white, "DEBUG2" hl.<< "# Hypersonic Memory Leak #".hight_white, "DEBUG2" hl.<< "# #".hight_white, "DEBUG2" hl.<< "################################################################################################".hight_white, "DEBUG2" hl.<< "# #".hight_white, "DEBUG2" hl.<< "# Le seguenti allocazioni di memoria possono essere generate in due modi: #".hight_white, "DEBUG2" hl.<< "# #".hight_white, "DEBUG2" hl.<< "# - By connect: in questo caso la tabella sotto mostra il receiver, il metodo e i parametri #".hight_white, "DEBUG2" hl.<< "# es. tr.connect(:ondblclick, self, 'doubleClick', id: @oid, ...) #".hight_white, "DEBUG2" hl.<< "# #".hight_white, "DEBUG2" hl.<< "# - By malloc: in questo caso la tabella sotto mostra l'oggetto usato #".hight_white, "DEBUG2" hl.<< "# es. @oid = hm().malloc(@modelName.clone, poid).obj.object_id.to_s #".hight_white, "DEBUG2" hl.<< "# #".hight_white, "DEBUG2" hl.<< "# - Le righe in rosso sono quelle senza parent (vericare che ce ne sia solo una) #".hight_white, "DEBUG2" hl.<< "# Se ce sono piu' di una e si vuole capire da dove proviene il metodo alloc genera #".hight_white, "DEBUG2" hl.<< "# un Warning rosso quando si esegue una malloc senza poid #".hight_white, "DEBUG2" hl.<< "# #".hight_white, "DEBUG2" hl.<< "################################################################################################".hight_white, "DEBUG2" usedMemory = "[Used Memory]#: #{@memory.length} blocks".hight_cyan hl.<< "# #{usedMemory} ".hight_white, "DEBUG2" hl.<< "################################################################################################".hight_white, "DEBUG2" memory = (sorted) ? @memory.sort_by { |oid, node| node.updateTimestamp } : @memory memory.each do |oid, node| node.show(oid: oid) end return memory end
test()
click to toggle source
# File lib/hengine/hmalloc.rb, line 230 def test m = hm() a1 = "LevelA-1" l1 = "Level 1" l2a = "Level 2-a" l2b = "Level 2-b" l2c = "Level 2-c" l3a = "Level 3-a" l3b = "Level 3-b" l3c = "Level 3-c" node = m.malloc2(l1) m.malloc2(a1) m.malloc2(l2a, l1) m.malloc2(l2b, l1) m.malloc2(l2c, l1) m.malloc2(l3a, l2a) m.malloc2(l3b, l2a) m.malloc2(l3c, l2a) m.show sleep(3) p m.get(l3c.object_id) m.clean # La cancellazione avviene solo impostazione @expiration = 3 in quanto sleep = 3 m.show end