Class gc
This difference becomes most notable if finalizers are involved that perform resurrection. While the resurrected object itself behaves rather similar between Jython and CPython, things are more delicate with objects that are reachable (i.e. strongly referenced) via the resurrected object exclusively. While in CPython such objects do not get their finalizers called, Jython/Java would call all their finalizers. That is because Java detects the whole unreachable subgraph as garbage and thus calls all their finalizers without any chance of direct intervention. CPython instead detects the unreachable object and calls its finalizer, which makes the object reachable again. Then all other objects are reachable from it and CPython does not treat them as garbage and does not call their finalizers at all. This further means that in Jython weak references to such indirectly resurrected objects break, while these persist in CPython.
As of Jython 2.7, the gc module offers some options to emulate CPython behavior. Especially see
the flags PRESERVE_WEAKREFS_ON_RESURRECTION
, DONT_FINALIZE_RESURRECTED_OBJECTS
and DONT_FINALIZE_CYCLIC_GARBAGE
for this.
Another difference is that CPython's gc module offers some debug features like counting of
collected cyclic trash, which are hard to support by Jython. As of Jython 2.7 the introduction of
a traverseproc mechanism (c.f. Traverseproc
) made support of these
features feasible. As support of these features comes with a significant emulation cost, one must
explicitly tell gc to perform this. To make objects subject to cyclic trash counting, these
objects must be gc-monitored in Jython. See monitorObject(PyObject)
,
unmonitorObject(PyObject)
, MONITOR_GLOBAL
and stopMonitoring()
for
this.
If at least one object is gc-monitored, collect()
works synchronously in the sense that
it blocks until all gc-monitored objects that are garbage actually have been collected and had
their finalizers called and completed. collect()
will report the number of collected
objects in the same manner as in CPython, i.e. counts only those that participate in reference
cycles. This allows a unified test implementation across Jython and CPython (which applies to
most tests in test_gc.py). If not any object is gc-monitored, collect()
just delegates
to System.gc()
, runs asynchronously (i.e. non-blocking) and returns
UNKNOWN_COUNT
. See also DEBUG_SAVEALL
for a useful gc debugging feature that is
supported by Jython from version 2.7 onwards.
Implementing all these features in Jython involved a lot of synchronization logic. While care was
taken to implement this without using timeouts as far as possible and rely on locks, states and
system/hardware independent synchronization techniques, this was not entirely feasible.
The aspects that were only feasible using a timeout are waiting for gc to enqueue all collected
objects (i.e. weak references to monitored objects that were gc'ed) to the reference queue and
waiting for gc to run all PyObject finalizers.
Waiting for trash could in theory be strictly synchronized by using MXBean
s, i.e.
GarbageCollectionNotificationInfo and related API. However, experiments
showed that the arising gc notifications do not reliably indicate when enqueuing was done for a
specific gc run. We kept the experimental implementation in source code comments to allow easy
reproducibility of this issue. (Note that out commented code contradicts Jython styleguide, but
this one - however - is needed to document this infeasible approach and is explicitly declared
accordingly).
But how is sync done now? We insert a sentinel before running gc and wait until this
sentinel was collected. Timestamps are taken to give us an idea at which time scales the gc of
the current JVM performs. We then wait until twice the measured time (i.e. duration from call to
System.gc()
until the sentinel reference was enqueued) has passed after the
last reference was enqueued by gc. While this approach is not entirely safe in theory, it passes
all tests on various systems and machines we had available for testing so far. We consider it
more robust than a fixed-length timeout and regard it the best known feasible compromise to
emulate synchronous gc runs in Java.
The other timing-based synchronization issue - waiting for finalizers to run - is solved as
follows. Since PyObject finalizers are based on
FinalizeTrigger
s, Jython has full control about these
finalization process from a central point. Before such a finalizer runs, it calls
notifyPreFinalization()
and when it is done, it calls notifyPostFinalization()
.
While processing of a finalizer can be of arbitrary duration, it widely holds that Java's gc
thread calls the next finalizer almost instantaneously after the former. That means that a
timestamp taken in notifyPreFinalization()
is usually delayed only few milliseconds -
often even reported as 0 milliseconds - after the last taken timestamp in
notifyPostFinalization()
(i.e. that was called by the previous finalizer). Jython's gc
module assumes the end of Java's finalization process if postFinalizationTimeOut
milliseconds passed after a call of notifyPostFinalization()
without another call to
notifyPreFinalization()
in that time. The default value of
postFinalizationTimeOut
is 100
, which is far larger than the usual almost-zero
duration between finalizer calls.
This process can be disturbed by third-party finalizers of non-PyObjects brought into the process
by external libraries. If these finalizers are of short duration (which applies to typical
finalizers), one can deal with this by adjusting postFinalizationTimeOut
, which was
declared public
for exactly this purpose. However if the external framework causing the
issue is Jython aware, a cleaner solution would be to let its finalizers call
notifyPreFinalization()
and notifyPostFinalization()
appropriately. In that
case these finalizers must not terminate by throwing an exception before
notifyPostFinalization()
was called. This is a strict requirement, since a deadlock can
be caused otherwise.
Note that the management API (c.f. com.sun.management.GarbageCollectionNotificationInfo) does not emit any notifications that allow to detect the end of the finalization phase. So this API provides no alternative to the described technique.
Usually Java's gc provides hardly any guarantee about its collection and finalization process. It
not even guarantees that finalizers are called at all (c.f.
http://howtodoinjava.com/2012/10/31/why-not-to-use-finalize-method-in-java). While
at least the most common JVM implementations usually do call finalizers reliably under
normal conditions, there still is no specific finalization order guaranteed (one might reasonably
expect that this would be related to reference connection graph topology, but this appears not to
be the case). However Jython now offers some functionality to compensate this situation. Via
registerPreFinalizationProcess(Runnable)
and
registerPostFinalizationProcess(Runnable)
and related methods one can now listen to
beginning and end of the finalization process. Note that this functionality relies on the
technique described in the former paragraph (i.e. based on calls to
notifyPreFinalization()
and notifyPostFinalization()
) and thus underlies its
unsafety, if third-party finalizers are involved. Such finalizers can cause false-positive runs
of registered (pre/post) finalization processes, so this feature should be used with some care.
It is recommended to use it only in such a way that false-positive runs would not cause serious
harm, but only some loss in performance or so.
-
Nested Class Summary
-
Field Summary
Modifier and TypeFieldDescriptionstatic final String
static final PyString
static final PyString
static final PyString
static final PyString
static final PyString
static final PyString
static final PyString
static final PyString
static final PyString
static final PyString
static final PyString
static final PyString
static final PyString
static final String
static final int
print collectable objects (in Jython scoped on monitored objects)static final int
print instances (in Jython scoped on monitored objects)static final int
Bit combination of the flagsDEBUG_COLLECTABLE
,DEBUG_UNCOLLECTABLE
,DEBUG_INSTANCES
,DEBUG_OBJECTS
,DEBUG_SAVEALL
.static final int
print other objects (in Jython scoped on monitored objects)static final int
save all garbage in gc.garbage (in Jython scoped on monitored objects)static final int
print collection statistics (in Jython scoped on monitored objects)static final int
print uncollectable objects (in Jython scoped on monitored objects)static final short
CPython prior to 3.4 does not finalize cyclic garbage PyObjects, while Jython does this by default.static final short
If in CPython an object is resurrected via its finalizer and contained strong references to other objects, these are also resurrected and not finalized in CPython (as their reference count never drops to zero).static final short
Reflection-based traversal is an inefficient fallback method to traverse PyObject subtypes that don't implementTraverseproc
and are not marked asUntraversable
.static final short
static final short
static PyList
list of uncollectable objectsstatic long
static final short
Makes gc emit reflection-based traversal warning for every traversed object instead of only once per class.static final short
This flag tells every newly created PyObject to register for gc monitoring.static long
static final short
If a PyObject is resurrected during its finalization process and was weakly referenced, Jython breaks the weak references to the resurrected PyObject by default.static final short
If this flag is not set, gc warns whenever an object would be subject to reflection-based traversal.static final int
A constant that can occur as result ofcollect()
and indicates an unknown number of collected cyclic trash.static final short
In Jython one usually usesPy.writeDebug
for debugging output.static final short
static final short
Enables collection-related verbose output.static final short
Enables delayed finalization related verbose output.static final short
Enables finalization-related verbose output.static final short
Enables weakref-related verbose output. -
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionstatic void
static void
addJythonGCFlags
(short flags) This is a convenience method to add flags via bitwise or.static boolean
canLinkToPyObject
(Class<?> cls, boolean actual) This method checks via type-checking-only, whether an object of the given class can in principle hold a ref to aPyObject
.static int
collect()
If no objects are monitored, this just delegates toSystem.gc()
and returnsUNKNOWN_COUNT
as a non-erroneous default value.static int
collect
(int generation) The generation parameter is only for compatibility with CPythoncollect()
and is ignored.static boolean
static boolean
static void
disable()
Not supported by Jython.static void
enable()
Does nothing in Jython as Java gc is always enabled.findCyclicObjects
(PyObject start) Return objects that are reachable from start AND can reach start, thus participate in a cycle with start.static PyObject
Not supported by Jython.static int
Copied from CPython doc:
Get the garbage collection debugging flags.static PyObject
Only works reliably ifmonitorGlobal
is active, as it depends on monitored objects to search for referrers.static PyObject
get_referents
(PyObject[] args, String[] kwargs) Only works reliably if all objects in args properly implement the Traverseproc mechanism (unless reflection-based traversal is activated and works stable).static PyObject
get_referrers
(PyObject[] args, String[] kwargs) Only works reliably ifmonitorGlobal
is active, as it depends on monitored objects to search for referrers.static PyObject
Not supported by Jython.static short
Gets the current Jython specific gc flags.static boolean
static org.python.modules.gc.WeakReferenceGC
Avoid to use this method.static int
indexOfPostFinalizationProcess
(Runnable process) static int
indexOfPreFinalizationProcess
(Runnable process) static PyObject
is_tracked
(PyObject[] args, String[] kwargs) is_tracked
is - in Jython case - interpreted in the sense thatgc.collect
will be able to count the object as collected if it participates in a cycle.static boolean
Always returnstrue
in Jython.static boolean
isMonitored
(PyObject ob) static boolean
static boolean
static void
markCyclicObjects
(PyObject start, boolean uncollectable) Mark all objects that are reachable from start AND can reach start, thus participate in a cycle with start.static void
static void
monitorObject
(PyObject ob, boolean initString) static void
notifyFinalize
(PyObject finalized) Do not call this method manually.static void
static void
static void
static void
registerPostFinalizationProcess
(Runnable process) Registers a process that will be called after all finalization during gc run is done ("finalization" refers to Jython style finalizers ran byFinalizeTrigger
s; to care for other finalizers these must callgc.notifyPreFinalization()
before anything else is done andgc.notifyPostFinalization()
afterwards; between these calls the finalizer must not terminate by throwing an exception).static void
registerPostFinalizationProcess
(Runnable process, int index) See doc ofregisterPostFinalizationProcess(Runnable)
.static void
registerPreFinalizationProcess
(Runnable process) Registers a process that will be called before any finalization during gc run takes place ("finalization" refers to Jython style finalizers ran byFinalizeTrigger
s; to care for other finalizers these must callgc.notifyPreFinalization()
before anything else is done andgc.notifyPostFinalization()
afterwards; between these calls the finalizer must not terminate by throwing an exception).static void
registerPreFinalizationProcess
(Runnable process, int index) See doc ofregisterPreFinalizationProcess(Runnable)
.static void
removeJythonGCFlags
(short flags) This is a convenience method to remove flags via bitwise and-not.static void
restoreFinalizer
(PyObject obj) In addition to whatFinalizeTrigger.ensureFinalizer(PyObject)
does, this method also restores the finalizer'sFinalizeTrigger
's flags by taking the values from the former finalizer.static void
Restores weak references pointing torst
.static void
set_debug
(int flags) Copied from CPython doc:
Set the garbage collection debugging flags.static void
set_threshold
(PyObject[] args, String[] kwargs) Not supported by Jython.static void
setJythonGCFlags
(short flags) Sets the current Jython specific gc flags.static void
setMonitorGlobal
(boolean flag) static void
static int
Does its best to traverse the givenPyObject
ob
.static int
traverseByReflection
(Object ob, Visitproc visit, Object arg) This method recursively traverses fields ofob
.static void
static boolean
static boolean
static void
Useful if a process wants to remove another one or itself during its execution.static boolean
unregisterPreFinalizationProcess
(Runnable process) static void
Useful if a process wants to remove another one or itself during its execution.static void
writeDebug
(String type, String msg) Works likePrePy.writeDebug(String, String)
, but prints toPrePy.writeDebug(String, String)
(i.e. subject to Jython's verbose level) or directly toSystem.err
, according toUSE_PY_WRITE_DEBUG
.
-
Field Details
-
UNKNOWN_COUNT
public static final int UNKNOWN_COUNTA constant that can occur as result ofcollect()
and indicates an unknown number of collected cyclic trash. It is intentionally not valued -1 as that value is reserved to indicate an error.- See Also:
-
MONITOR_GLOBAL
public static final short MONITOR_GLOBALThis flag tells every newly created PyObject to register for gc monitoring. This allowscollect()
to report the number of collected objects. -
DONT_FINALIZE_CYCLIC_GARBAGE
public static final short DONT_FINALIZE_CYCLIC_GARBAGECPython prior to 3.4 does not finalize cyclic garbage PyObjects, while Jython does this by default. This flag tells Jython's gc to mimic CPython <3.4 behavior (i.e. add such objects togc.garbage
list instead). -
PRESERVE_WEAKREFS_ON_RESURRECTION
public static final short PRESERVE_WEAKREFS_ON_RESURRECTIONIf a PyObject is resurrected during its finalization process and was weakly referenced, Jython breaks the weak references to the resurrected PyObject by default. In CPython these persist, if the object was indirectly resurrected due to resurrection of its owner. This flag tells Jython's gc to preserve weak references to such resurrected PyObjects. It only works if all involved objects implement the traverseproc mechanism properly (seeTraverseproc
). Note that this feature comes with some cost as it can delay garbage collection of some weak referenced objects for several gc cycles if activated. So we recommend to use it only for debugging. -
DONT_FINALIZE_RESURRECTED_OBJECTS
public static final short DONT_FINALIZE_RESURRECTED_OBJECTSIf in CPython an object is resurrected via its finalizer and contained strong references to other objects, these are also resurrected and not finalized in CPython (as their reference count never drops to zero). In contrast to that, Jython calls finalizers for all objects that were unreachable when gc started (regardless of resurrections and in unpredictable order). This flag emulates CPython behavior in Jython. Note that this emulation comes with a significant cost as it can delay collection of many objects for several gc cycles. Its main intention is for debugging resurrection-sensitive code. -
FORCE_DELAYED_FINALIZATION
public static final short FORCE_DELAYED_FINALIZATION- See Also:
-
FORCE_DELAYED_WEAKREF_CALLBACKS
public static final short FORCE_DELAYED_WEAKREF_CALLBACKS- See Also:
-
DONT_TRAVERSE_BY_REFLECTION
public static final short DONT_TRAVERSE_BY_REFLECTIONReflection-based traversal is an inefficient fallback method to traverse PyObject subtypes that don't implement
Traverseproc
and are not marked asUntraversable
. Such a situation indicates that the programmer was not aware of Jython's traverseproc mechanism and reflection is used to compensate this.This flag allows to inhibit reflection-based traversal. If it is activated, objects that don't implement
Traverseproc
are always treated as if they were marked asUntraversable
.Note that reflection-based traversal fallback is performed by default. Further note that Jython emits warning messages if reflection-based traversal occurs or if an object is encountered that neither implements
Traverseproc
nor is marked asUntraversable
(even if reflection-based traversal is inhibited). SeeSUPPRESS_TRAVERSE_BY_REFLECTION_WARNING
andINSTANCE_TRAVERSE_BY_REFLECTION_WARNING
to control these warning messages. -
SUPPRESS_TRAVERSE_BY_REFLECTION_WARNING
public static final short SUPPRESS_TRAVERSE_BY_REFLECTION_WARNINGIf this flag is not set, gc warns whenever an object would be subject to reflection-based traversal. Note that if this flag is not set, the warning will occur even if reflection-based traversal is not active. The purpose of this behavior is to identify objects that don't properly support the traverseproc mechanism, i.e. instances of PyObject subclasses that neither implement
Traverseproc
, nor are annotated with theUntraversable
annotation.A SUPPRESS flag was chosen rather than a WARN flag, so that warning is the default behavior - the user must actively set this flag in order to not to be warned. This is because in an ideal implementation reflection-based traversal never occurs; it is only an inefficient fallback.
-
INSTANCE_TRAVERSE_BY_REFLECTION_WARNING
public static final short INSTANCE_TRAVERSE_BY_REFLECTION_WARNINGMakes gc emit reflection-based traversal warning for every traversed object instead of only once per class. A potential reflection-based traversal occurs whenever an object is traversed that neither implementsTraverseproc
, nor is annotated with theUntraversable
annotation. -
USE_PY_WRITE_DEBUG
public static final short USE_PY_WRITE_DEBUGIn Jython one usually usesPy.writeDebug
for debugging output. However that method is only verbose if an appropriate verbose level was set. In CPython it is enough to set gcDEBUG
flags to get gc messages, no matter what overall verbose level is selected. This flag tells Jython to usePy.writeDebug
for debugging output. If it is not set (default case), gc debugging output (if gcVERBOSE
orDEBUG
flags are set) is directly written toSystem.err
. -
VERBOSE_COLLECT
public static final short VERBOSE_COLLECTEnables collection-related verbose output. -
VERBOSE_WEAKREF
public static final short VERBOSE_WEAKREFEnables weakref-related verbose output. -
VERBOSE_DELAYED
public static final short VERBOSE_DELAYEDEnables delayed finalization related verbose output. -
VERBOSE_FINALIZE
public static final short VERBOSE_FINALIZEEnables finalization-related verbose output. -
VERBOSE
public static final short VERBOSE -
DEBUG_STATS
public static final int DEBUG_STATSprint collection statistics (in Jython scoped on monitored objects)- See Also:
-
DEBUG_COLLECTABLE
public static final int DEBUG_COLLECTABLEprint collectable objects (in Jython scoped on monitored objects)- See Also:
-
DEBUG_UNCOLLECTABLE
public static final int DEBUG_UNCOLLECTABLEprint uncollectable objects (in Jython scoped on monitored objects)- See Also:
-
DEBUG_INSTANCES
public static final int DEBUG_INSTANCESprint instances (in Jython scoped on monitored objects)- See Also:
-
DEBUG_OBJECTS
public static final int DEBUG_OBJECTSprint other objects (in Jython scoped on monitored objects)- See Also:
-
DEBUG_SAVEALL
public static final int DEBUG_SAVEALLsave all garbage in gc.garbage (in Jython scoped on monitored objects)- See Also:
-
DEBUG_LEAK
public static final int DEBUG_LEAKBit combination of the flagsDEBUG_COLLECTABLE
,DEBUG_UNCOLLECTABLE
,DEBUG_INSTANCES
,DEBUG_OBJECTS
,DEBUG_SAVEALL
.- See Also:
-
gcRecallTime
public static long gcRecallTime -
garbage
list of uncollectable objects -
postFinalizationTimeOut
public static long postFinalizationTimeOut -
__doc__
- See Also:
-
__name__
- See Also:
-
__doc__enable
-
__doc__disable
-
__doc__isenabled
-
__doc__collect
-
__doc__get_count
-
__doc__set_debug
-
__doc__get_debug
-
__doc__set_thresh
-
__doc__get_thresh
-
__doc__get_objects
-
__doc__is_tracked
-
__doc__get_referrers
-
__doc__get_referents
-
-
Constructor Details
-
gc
public gc()
-
-
Method Details
-
writeDebug
Works likePrePy.writeDebug(String, String)
, but prints toPrePy.writeDebug(String, String)
(i.e. subject to Jython's verbose level) or directly toSystem.err
, according toUSE_PY_WRITE_DEBUG
. -
restoreFinalizer
In addition to whatFinalizeTrigger.ensureFinalizer(PyObject)
does, this method also restores the finalizer'sFinalizeTrigger
's flags by taking the values from the former finalizer. On the other hand - in contrast toFinalizeTrigger.ensureFinalizer(PyObject)
- this method would not create aFinalizeTrigger
for an object that did not have one before (i.e. the method checks for an old (dead) trigger before it creates a new one.
If a new finalizer is needed due to an ordinary resurrection (i.e. the object's finalizer was called),FinalizeTrigger.ensureFinalizer(PyObject)
is the right choice. If a finalization was vetoed in context of delayed finalization (i.e. a resurrection that pretends not to be one and didn't run the finalizer), this method is the better choice as it helps to make the newFinalizeTrigger
look exactly like the old one regarding flags etc. E.g. this method is called byabortDelayedFinalization(PyObject)
.- See Also:
-
restoreWeakReferences
Restores weak references pointing torst
. Note that this does not prevent callbacks, unless it is called during finalization phase (e.g. by a finalizer) anddelayedWeakrefCallbacksEnabled()
returnstrue
. In a manual fashion, one can enforce this by using the gc flagFORCE_DELAYED_WEAKREF_CALLBACKS
. Alternatively, one can use the automatic way via the gc flagPRESERVE_WEAKREFS_ON_RESURRECTION
, but then one would not need to call this method anyway. The manual way has better performance, but also brings more responsibilies. -
delayedWeakrefCallbacksEnabled
public static boolean delayedWeakrefCallbacksEnabled() -
delayedFinalizationEnabled
public static boolean delayedFinalizationEnabled() -
registerForDelayedFinalization
-
abortDelayedFinalization
-
registerPreFinalizationProcess
Registers a process that will be called before any finalization during gc run takes place ("finalization" refers to Jython style finalizers ran by
FinalizeTrigger
s; to care for other finalizers these must callgc.notifyPreFinalization()
before anything else is done andgc.notifyPostFinalization()
afterwards; between these calls the finalizer must not terminate by throwing an exception). This works independently from monitoring, which is mainly needed to allow counting of cyclic garbage incollect()
.This feature compensates that Java's gc does not provide any guarantees about finalization order. Java not even guarantees that when a weak reference is added to a reference queue, its finalizer already ran or not yet ran, if any.
The only guarantee is that
PhantomReference
s are enqueued after finalization of their referents, but this happens in another gc cycle then.Actually there are still situations that can cause pre finalization process to run again during finalization phase. This can happen if external frameworks use their own finalizers. This can be cured by letting these finalizers call
gc.notifyPreFinalization()
before anything else is done andgc.notifyPostFinalization()
right before the finalization method returns. Between these calls the finalizer must not terminate by throwing an exception.We recommend to use this feature in a way such that false-positive runs are not critically harmful, e.g. use it to enhance performance, but don't let it cause a crash if preprocess is rerun unexpectedly.
-
registerPreFinalizationProcess
See doc ofregisterPreFinalizationProcess(Runnable)
. -
indexOfPreFinalizationProcess
-
unregisterPreFinalizationProcess
-
unregisterPreFinalizationProcessAfterNextRun
Useful if a process wants to remove another one or itself during its execution. This asynchronous unregister method circumvents the synchronized state on pre finalization process list. -
registerPostFinalizationProcess
Registers a process that will be called after all finalization during gc run is done ("finalization" refers to Jython style finalizers ran by
FinalizeTrigger
s; to care for other finalizers these must callgc.notifyPreFinalization()
before anything else is done andgc.notifyPostFinalization()
afterwards; between these calls the finalizer must not terminate by throwing an exception). This works independently from monitoring (which is mainly needed to allow garbage counting incollect()
).This feature compensates that Java's gc does not provide any guarantees about finalization order. Java not even guarantees that when a weak reference is added to a reference queue, its finalizer already ran or not yet ran, if any.
The only guarantee is that
PhantomReference
s are enqueued after finalization of the referents, but this happens - however - in another gc cycle then.There are situations that can cause post finalization process to run already during finalization phase. This can happen if external frameworks use their own finalizers. This can be cured by letting these finalizers call
gc.notifyPreFinalization()
before anything else is done andgc.notifyPostFinalization()
right before the finalization method returns. Between these calls the finalizer must not terminate by throwing an exception.If it runs too early, we can at least guarantee that it will run again after finalization was really done. So we recommend to use this feature in a way such that false-positive runs are not critically harmful.
-
registerPostFinalizationProcess
See doc ofregisterPostFinalizationProcess(Runnable)
. -
indexOfPostFinalizationProcess
-
unregisterPostFinalizationProcess
-
unregisterPostFinalizationProcessAfterNextRun
Useful if a process wants to remove another one or itself during its execution. This asynchronous unregister method circumvents the synchronized state on post finalization process list. -
notifyPreFinalization
public static void notifyPreFinalization() -
notifyPostFinalization
public static void notifyPostFinalization() -
monitorObject
-
monitorObject
-
getMonitorReference
Avoid to use this method. It is inefficient and no intended purpose of the backing Set of objects. In normal business it should not be needed and only exists for bare debugging purposes. -
isMonitoring
public static boolean isMonitoring() -
isMonitored
-
unmonitorObject
-
unmonitorAll
public static void unmonitorAll() -
stopMonitoring
public static void stopMonitoring() -
getMonitorGlobal
public static boolean getMonitorGlobal() -
setMonitorGlobal
public static void setMonitorGlobal(boolean flag) -
getJythonGCFlags
public static short getJythonGCFlags()Gets the current Jython specific gc flags.- See Also:
-
MONITOR_GLOBAL
DONT_FINALIZE_CYCLIC_GARBAGE
PRESERVE_WEAKREFS_ON_RESURRECTION
DONT_FINALIZE_RESURRECTED_OBJECTS
DONT_TRAVERSE_BY_REFLECTION
SUPPRESS_TRAVERSE_BY_REFLECTION_WARNING
INSTANCE_TRAVERSE_BY_REFLECTION_WARNING
USE_PY_WRITE_DEBUG
VERBOSE_COLLECT
VERBOSE_WEAKREF
VERBOSE_DELAYED
VERBOSE_FINALIZE
VERBOSE
setJythonGCFlags(short)
addJythonGCFlags(short)
removeJythonGCFlags(short)
-
setJythonGCFlags
public static void setJythonGCFlags(short flags) Sets the current Jython specific gc flags.
flags
is ashort
and can have the following bits turned on:
MONITOR_GLOBAL
- Automatically monitors all PyObjects created from now on.
DONT_FINALIZE_CYCLIC_GARBAGE
- Adds cyclic finalizable PyObjects togarbage
.
PRESERVE_WEAKREFS_ON_RESURRECTION
- Keeps weak references alive if the referent is resurrected.
DONT_FINALIZE_RESURRECTED_OBJECTS
- Emulates CPython behavior regarding resurrected objects and finalization.
DONT_TRAVERSE_BY_REFLECTION
- Inhibits reflection-based traversal.
SUPPRESS_TRAVERSE_BY_REFLECTION_WARNING
- Suppress warnings for PyObjects that neither implementTraverseproc
nor are marked asUntraversable
.
USE_PY_WRITE_DEBUG
- usesPrePy.writeDebug(String, String)
for debugging output instead of directly writing toSystem.err
.
VERBOSE_COLLECT
- Enable collection-related verbose output.
VERBOSE_WEAKREF
- Enable weakref-related verbose output.
VERBOSE_DELAYED
- Enable delayed finalization-related verbose output.
VERBOSE_FINALIZE
- Enable finalization-related verbose output.
VERBOSE
- All previous verbose-flags combined.- See Also:
-
MONITOR_GLOBAL
DONT_FINALIZE_CYCLIC_GARBAGE
PRESERVE_WEAKREFS_ON_RESURRECTION
DONT_FINALIZE_RESURRECTED_OBJECTS
DONT_TRAVERSE_BY_REFLECTION
SUPPRESS_TRAVERSE_BY_REFLECTION_WARNING
INSTANCE_TRAVERSE_BY_REFLECTION_WARNING
USE_PY_WRITE_DEBUG
VERBOSE_COLLECT
VERBOSE_WEAKREF
VERBOSE_DELAYED
VERBOSE_FINALIZE
VERBOSE
getJythonGCFlags()
addJythonGCFlags(short)
removeJythonGCFlags(short)
-
addJythonGCFlags
public static void addJythonGCFlags(short flags) This is a convenience method to add flags via bitwise or.- See Also:
-
MONITOR_GLOBAL
DONT_FINALIZE_CYCLIC_GARBAGE
PRESERVE_WEAKREFS_ON_RESURRECTION
DONT_FINALIZE_RESURRECTED_OBJECTS
DONT_TRAVERSE_BY_REFLECTION
SUPPRESS_TRAVERSE_BY_REFLECTION_WARNING
INSTANCE_TRAVERSE_BY_REFLECTION_WARNING
USE_PY_WRITE_DEBUG
VERBOSE_COLLECT
VERBOSE_WEAKREF
VERBOSE_DELAYED
VERBOSE_FINALIZE
VERBOSE
getJythonGCFlags()
setJythonGCFlags(short)
removeJythonGCFlags(short)
-
removeJythonGCFlags
public static void removeJythonGCFlags(short flags) This is a convenience method to remove flags via bitwise and-not.- See Also:
-
MONITOR_GLOBAL
DONT_FINALIZE_CYCLIC_GARBAGE
PRESERVE_WEAKREFS_ON_RESURRECTION
DONT_FINALIZE_RESURRECTED_OBJECTS
DONT_TRAVERSE_BY_REFLECTION
SUPPRESS_TRAVERSE_BY_REFLECTION_WARNING
INSTANCE_TRAVERSE_BY_REFLECTION_WARNING
USE_PY_WRITE_DEBUG
VERBOSE_COLLECT
VERBOSE_WEAKREF
VERBOSE_DELAYED
VERBOSE_FINALIZE
VERBOSE
getJythonGCFlags()
setJythonGCFlags(short)
addJythonGCFlags(short)
-
notifyFinalize
Do not call this method manually. It should only be called byFinalizeTrigger
. -
enable
public static void enable()Does nothing in Jython as Java gc is always enabled. -
disable
public static void disable()Not supported by Jython.- Throws:
PyException
-NotImplementedError
-
isenabled
public static boolean isenabled()Always returnstrue
in Jython. -
collect
public static int collect(int generation) The generation parameter is only for compatibility with CPythoncollect()
and is ignored.- Parameters:
generation
- (ignored)- Returns:
- Collected monitored cyclic trash objects or
gc.UNKNOWN_COUNT
if nothing is monitored or -1 if an error occurred and collection did not complete. - See Also:
-
collect
public static int collect()If no objects are monitored, this just delegates toSystem.gc()
and returnsUNKNOWN_COUNT
as a non-erroneous default value. If objects are monitored, it emulates a synchronous gc run in the sense that it waits until all collected monitored objects were finalized.- Returns:
- Number of collected monitored cyclic trash objects
or
UNKNOWN_COUNT
if nothing is monitored or -1 if an error occurred and collection did not complete. - See Also:
-
get_count
Not supported by Jython.- Throws:
PyException
-NotImplementedError
-
set_debug
public static void set_debug(int flags) Copied from CPython doc:
Set the garbage collection debugging flags. Debugging information is written toSystem.err
.
flags
flags is anint
eger and can have the following bits turned on:
DEBUG_STATS
- Print statistics during collection.
DEBUG_COLLECTABLE
- Print collectable objects found.
DEBUG_UNCOLLECTABLE
- Print unreachable but uncollectable objects found.
DEBUG_INSTANCES
- Print instance objects.
DEBUG_OBJECTS
- Print objects other than instances.
DEBUG_SAVEALL
- Save objects to gc.garbage rather than freeing them.
DEBUG_LEAK
- Debug leaking programs (everything but STATS). -
get_debug
public static int get_debug()Copied from CPython doc:
Get the garbage collection debugging flags. -
set_threshold
Not supported by Jython.- Throws:
PyException
-NotImplementedError
-
get_threshold
Not supported by Jython.- Throws:
PyException
-NotImplementedError
-
get_objects
Only works reliably ifmonitorGlobal
is active, as it depends on monitored objects to search for referrers. It only finds referrers that properly implement the traverseproc mechanism (unless reflection-based traversal is activated and works stable).- Throws:
PyException
-NotImplementedError
-
get_referrers
Only works reliably ifmonitorGlobal
is active, as it depends on monitored objects to search for referrers. It only finds referrers that properly implement the traverseproc mechanism (unless reflection-based traversal is activated and works stable). Further note that the resulting list will contain referrers in no specific order and may even include duplicates. -
get_referents
Only works reliably if all objects in args properly implement the Traverseproc mechanism (unless reflection-based traversal is activated and works stable). Further note that the resulting list will contain referents in no specific order and may even include duplicates. -
is_tracked
is_tracked
is - in Jython case - interpreted in the sense thatgc.collect
will be able to count the object as collected if it participates in a cycle. This mimics CPython behavior and passes the corresponding unit test intest_gc.py
. -
markCyclicObjects
Mark all objects that are reachable from start AND can reach start, thus participate in a cycle with start. -
findCyclicObjects
Return objects that are reachable from start AND can reach start, thus participate in a cycle with start. Returnsnull
if start does not participate in any cycle. -
traverse
Does its best to traverse the givenPyObject
ob
. It exploits bothTraverseproc.traverse(Visitproc, Object)
andTraverseprocDerived.traverseDerived(Visitproc, Object)
. Ifob
neither implementsTraverseproc
norTraverseproc
and is not annotated withUntraversable
, reflection-based traversal viatraverseByReflection(Object, Visitproc, Object)
may be attempted according toDONT_TRAVERSE_BY_REFLECTION
. -
traverseByReflection
This method recursively traverses fields of
ob
. If a field is a PyObject, it is passed tovisit
. and recursion ends in that branch. If a field is an array, the elements are checked whether they are PyObjects.PyObject
elements are passed tovisit
. Elements that are arrays themselves are again processed elementwise and so on.Through the whole search this method fails fast if
visit
returns non-zero.Note that we intentionally don't traverse iterables by iterating them. Since we perform recursion, this should reach all contained references anyway - in Java every object can only contain references as fields or arrays. On the one hand, exploiting iterables would ease the access to private fields, but on the other hand during iteration they might change inner state, create new (Py)Objects or obtain objects from native methods. Additionally we might run into concurrent modification issues. So all in all the traversal is cleaner and safer if just fields and arrays are traversed.
-
canLinkToPyObject
This method checks via type-checking-only, whether an object of the given class can in principle hold a ref to a
PyObject
. Especially if arrays are involved, this can safe a lot performance. For now, no generic type info is exploited.If
actual
is true, the answer will hold for an object that is an instance of the given class. Otherwise it is assumed that cls is the type of a field holding an object, so cls is considered as upper bound for an objects actual type.One should call with
actual == true
, if cls was obtained byob.getClass()
and withactual == false
, if cls was obtained as a field type or component type of an array. -
isTraversable
-