20,741
edits
| Line 125: | Line 125: | ||
:: As a crude workaround, you could expose the GC via an extension function, to explicitly trigger it in your code, and then watch the stats afterwards: IF the stats do not decrease after your explicit GC calls, objects are still somewhere referenced, i.e. cannot be reclaimed - maybe because of naTempSave() calls ? In general, memory isn't immediately reclaimed - but only after the GC could run, the amount of necessary GC work can be reduced by assigning nil and by delete()ing complex objects. Another thing worth trying would be associating naRefs with their origin (table of files and lines) using another naRef as a member, which would allow you to store the origin of naRefs directly inside them, and the dump everything to a file for inspection purposes. Adding an extension function that recursively dumps reachable naRefs (in a mark() fashion) should be straightforward and would tell us where the data came from that's still lingering around | :: As a crude workaround, you could expose the GC via an extension function, to explicitly trigger it in your code, and then watch the stats afterwards: IF the stats do not decrease after your explicit GC calls, objects are still somewhere referenced, i.e. cannot be reclaimed - maybe because of naTempSave() calls ? In general, memory isn't immediately reclaimed - but only after the GC could run, the amount of necessary GC work can be reduced by assigning nil and by delete()ing complex objects. Another thing worth trying would be associating naRefs with their origin (table of files and lines) using another naRef as a member, which would allow you to store the origin of naRefs directly inside them, and the dump everything to a file for inspection purposes. Adding an extension function that recursively dumps reachable naRefs (in a mark() fashion) should be straightforward and would tell us where the data came from that's still lingering around | ||
== Debugging Threads == | |||
Referring to: | |||
<syntaxhighlight lang="php"> | |||
268 DBG_LOCKS and print("Do_thread try lock"); | |||
269 thread.lock(queue_lock); | |||
270 DBG_LOCKS and print("Do_thread holds lock"); | |||
274 thread.unlock(queue_lock); | |||
275 DBG_LOCKS and print("Do_thread release lock"); | |||
</syntaxhighlight> | |||
Consider wrapping the low-level APIs to come up with classes, with built-in debugging support - which can also be extended (via inheritance) to add support for queues, stacks or other data structures: | |||
<syntaxhighlight lang="php"> | |||
var Lock = {}; | |||
Lock.new = func(name) { | |||
var temp = {parents:[Lock], name:name }; | |||
temp.LOCK=thread.newlock(); | |||
return temp; | |||
} | |||
Lock.lock = func { | |||
DBG_LOCKS and print("try lock:",me.name); | |||
thread.lock(me.LOCK); | |||
DBG_LOCKS and print("holds lock:",me.name); | |||
} | |||
Lock.unlock = func { | |||
thread.unlock(me.LOCK); | |||
DBG_LOCKS and print("lock released:",me.name); | |||
} | |||
var queue = Lock.new("queue lock"); | |||
</syntaxhighlight> | |||