org.python.modules

## Class gc

- java.lang.Object
- - org.python.modules.gc

    public class gc
    extends Object

In Jython, the gc-module notably differs from that in CPython. This comes from the different ways Jython and CPython perform garbage-collection. While CPython's garbage collection is based on reference-counting, Jython is backed by Java's gc, which is based on a mark-and-sweep-approach.

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 `java.lang.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

Nested Classes
`static class` `gc.CycleMarkAttr`

### Field Summary

Fields
`static String` `__doc__`
`static PyString` `__doc__collect`
`static PyString` `__doc__disable`
`static PyString` `__doc__enable`
`static PyString` `__doc__get_count`
`static PyString` `__doc__get_debug`
`static PyString` `__doc__get_objects`
`static PyString` `__doc__get_referents`
`static PyString` `__doc__get_referrers`
`static PyString` `__doc__get_thresh`
`static PyString` `__doc__is_tracked`
`static PyString` `__doc__isenabled`
`static PyString` `__doc__set_debug`
`static PyString` `__doc__set_thresh`
`static String` `__name__`
`static int` `DEBUG_COLLECTABLE` print collectable objects (in Jython scoped on monitored objects)
`static int` `DEBUG_INSTANCES` print instances (in Jython scoped on monitored objects)
`static int` `DEBUG_LEAK` Bit-combination of the flags `DEBUG_COLLECTABLE`, `DEBUG_UNCOLLECTABLE`, `DEBUG_INSTANCES`, `DEBUG_OBJECTS`, `DEBUG_SAVEALL`.
`static int` `DEBUG_OBJECTS` print other objects (in Jython scoped on monitored objects)
`static int` `DEBUG_SAVEALL` save all garbage in gc.garbage (in Jython scoped on monitored objects)
`static int` `DEBUG_STATS` print collection statistics (in Jython scoped on monitored objects)
`static int` `DEBUG_UNCOLLECTABLE` print uncollectable objects (in Jython scoped on monitored objects)
`static short` `DONT_FINALIZE_CYCLIC_GARBAGE` CPython prior to 3.4 does not finalize cyclic garbage PyObjects, while Jython does this by default.
`static short` `DONT_FINALIZE_RESURRECTED_OBJECTS` 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 short` `DONT_TRAVERSE_BY_REFLECTION` Reflection-based traversion is an inefficient fallback-method to traverse PyObject-subtypes that don't implement `Traverseproc` and are not marked as `Untraversable`.
`static PyList` `garbage` list of uncollectable objects
`static long` `gcRecallTime`
`static short` `INSTANCE_TRAVERSE_BY_REFLECTION_WARNING` Makes gc emit reflection-based traversion warning for every traversed object instead of only once per class.
`static short` `MONITOR_GLOBAL` This flag tells every newly created PyObject to register for gc-monitoring.
`static long` `postFinalizationTimeOut`
`static short` `PRESERVE_WEAKREFS_ON_RESURRECTION` 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 short` `SUPPRESS_TRAVERSE_BY_REFLECTION_WARNING` If this flag is not set, gc warns whenever an object would be subject to reflection-based traversion.
`static int` `UNKNOWN_COUNT` A constant that can occur as result of `collect()` and indicates an unknown number of collected cyclic trash.
`static short` `USE_PY_WRITE_DEBUG` In Jython one usually uses `Py.writeDebug` for debugging output.
`static short` `VERBOSE` Bit-combination of the flags `VERBOSE_COLLECT`, `VERBOSE_WEAKREF`, `VERBOSE_DELAYED`, `VERBOSE_FINALIZE`.
`static short` `VERBOSE_COLLECT` Enables collection-related verbose-output.
`static short` `VERBOSE_DELAYED` Enables delayed finalization related verbose-output.
`static short` `VERBOSE_FINALIZE` Enables finalization-related verbose-output.
`static short` `VERBOSE_WEAKREF` Enables weakref-related verbose-output.

### Constructor Summary

Constructors
Constructor and Description
`gc()`

### Method Summary

Methods
`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 a `PyObject`.
`static int` `collect()` If no objects are monitored, this just delegates to `System.gc()` and returns `UNKNOWN_COUNT` as a non-erroneous default value.
`static int` `collect(int generation)` The generation parameter is only for compatibility with CPython `gc.collect()` and is ignored.
`static boolean` `delayedFinalizationEnabled()`
`static void` `disable()` Not supported by Jython.
`static void` `enable()` Does nothing in Jython as Java-gc is always enabled.
`static Set<PyObject>` `findCyclicObjects(PyObject start)` Return objects that are reachable from start AND can reach start, thus participate in a cycle with start.
`static PyObject` `get_count()` Not supported by Jython.
`static int` `get_debug()` Copied from CPython-doc: Get the garbage collection debugging flags.
`static PyObject` `get_objects()` Not supported by Jython.
`static PyObject` `get_referents(PyObject[] args, String[] kwargs)` Only works reliably if all objects in args properly implement the Traverseproc mechanism (unless reflection-based traversion is activated and works stable).
`static PyObject` `get_referrers(PyObject[] args, String[] kwargs)` Only works reliably if `monitorGlobal` is active, as it depends on monitored objects to search for referrers.
`static PyObject` `get_threshold()` Not supported by Jython.
`static short` `getJythonGCFlags()` Gets the current Jython-specific gc-flags.
`static boolean` `getMonitorGlobal()`
`static org.python.modules.gc.WeakReferenceGC` `getMonitorReference(PyObject ob)` 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 that `gc.collect` will be able to count the object as collected if it participates in a cycle.
`static boolean` `isenabled()` Always returns `true` in Jython.
`static boolean` `isMonitored(PyObject ob)`
`static boolean` `isMonitoring()`
`static boolean` `isTraversable(PyObject ob)`
`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` `monitorObject(PyObject ob)`
`static void` `monitorObject(PyObject ob, boolean initString)`
`static void` `notifyFinalize(PyObject finalized)` Do not call this method manually.
`static void` `notifyPostFinalization()`
`static void` `notifyPreFinalization()`
`static void` `registerForDelayedFinalization(PyObject ob)`

`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 by `FinalizeTrigger`s; to care for other finalizers these must call `gc.notifyPreFinalization()` before anything else is done and `gc.notifyPostFinalization()` afterwards; between these calls the finalizer must not terminate by throwing an exception).

`static void` `registerPostFinalizationProcess(Runnable process, int index)` See doc of `registerPostFinalizationProcess(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 by `FinalizeTrigger`s; to care for other finalizers these must call `gc.notifyPreFinalization()` before anything else is done and `gc.notifyPostFinalization()` afterwards; between these calls the finalizer must not terminate by throwing an exception).

`static void` `registerPreFinalizationProcess(Runnable process, int index)` See doc of `registerPreFinalizationProcess(Runnable)`.
`static void` `removeJythonGCFlags(short flags)` This is a convenience method to remove flags via bitwise and-not.
`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` `stopMonitoring()`
`static int` `traverse(PyObject ob, Visitproc visit, Object arg)` Does its best to traverse the given `PyObject` `ob`.
`static int` `traverseByReflection(Object ob, Visitproc visit, Object arg)` This method recursively traverses fields of `ob`.
`static void` `unmonitorAll()`
`static boolean` `unmonitorObject(PyObject ob)`
`static boolean` `unregisterPostFinalizationProcess(Runnable process)`
`static void` `unregisterPostFinalizationProcessAfterNextRun(Runnable process)` Useful if a process wants to remove another one or itself during its execution.
`static boolean` `unregisterPreFinalizationProcess(Runnable process)`
`static void` `unregisterPreFinalizationProcessAfterNextRun(Runnable process)` Useful if a process wants to remove another one or itself during its execution.
`static void` `writeDebug(String type, String msg)` Works like `Py.writeDebug(String, String)`, but prints to `Py.writeDebug(String, String)` (i.e. subject to Jython's verbose level) or directly to `System.err`, according to `USE_PY_WRITE_DEBUG`.

### Methods inherited from class java.lang.Object

`equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

### Field Detail

#### UNKNOWN_COUNT

    public static final int UNKNOWN_COUNT

A constant that can occur as result of `collect()` 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:
  Constant Field Values

#### MONITOR_GLOBAL

    public static final short MONITOR_GLOBAL

This flag tells every newly created PyObject to register for gc-monitoring. This allows `collect()` to report the number of collected objects.

See Also:
  `setJythonGCFlags(short)`, `getJythonGCFlags()`, `addJythonGCFlags(short)`, `removeJythonGCFlags(short)`, Constant Field Values

#### DONT_FINALIZE_CYCLIC_GARBAGE

    public static final short DONT_FINALIZE_CYCLIC_GARBAGE

CPython 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 to `gc.garbage` list instead).

See Also:
  `setJythonGCFlags(short)`, `getJythonGCFlags()`, `addJythonGCFlags(short)`, `removeJythonGCFlags(short)`, Constant Field Values

#### PRESERVE_WEAKREFS_ON_RESURRECTION

    public static final short PRESERVE_WEAKREFS_ON_RESURRECTION

If 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 (see `Traverseproc`). 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.

See Also:
  `setJythonGCFlags(short)`, `getJythonGCFlags()`, `addJythonGCFlags(short)`, `removeJythonGCFlags(short)`, Constant Field Values

#### DONT_FINALIZE_RESURRECTED_OBJECTS

    public static final short DONT_FINALIZE_RESURRECTED_OBJECTS

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). 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.

See Also:
  `setJythonGCFlags(short)`, `getJythonGCFlags()`, `addJythonGCFlags(short)`, `removeJythonGCFlags(short)`, Constant Field Values

#### DONT_TRAVERSE_BY_REFLECTION

    public static final short DONT_TRAVERSE_BY_REFLECTION

Reflection-based traversion is an inefficient fallback-method to traverse PyObject-subtypes that don't implement `Traverseproc` and are not marked as `Untraversable`. 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 traversion. If it is activated, objects that don't implement `Traverseproc` are always treated as if they were marked as `Untraversable`.

Note that reflection-based traversion fallback is performed by default. Further note that Jython emits warning-messages if reflection-based traversion occurs or if an object is encountered that neither implements `Traverseproc` nor is marked as `Untraversable` (even if reflection-based traversion is inhibited). See `SUPPRESS_TRAVERSE_BY_REFLECTION_WARNING` and `INSTANCE_TRAVERSE_BY_REFLECTION_WARNING` to control these warning-messages.

See Also:
  `setJythonGCFlags(short)`, `getJythonGCFlags()`, `addJythonGCFlags(short)`, `removeJythonGCFlags(short)`, `SUPPRESS_TRAVERSE_BY_REFLECTION_WARNING`, `INSTANCE_TRAVERSE_BY_REFLECTION_WARNING`, Constant Field Values

#### SUPPRESS_TRAVERSE_BY_REFLECTION_WARNING

    public static final short SUPPRESS_TRAVERSE_BY_REFLECTION_WARNING

If this flag is not set, gc warns whenever an object would be subject to reflection-based traversion. Note that if this flag is not set, the warning will occur even if reflection-based traversion 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 the `Untraversable`-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 traversion never occurs; it is only an inefficient fallback.

See Also:
  `setJythonGCFlags(short)`, `getJythonGCFlags()`, `addJythonGCFlags(short)`, `removeJythonGCFlags(short)`, `INSTANCE_TRAVERSE_BY_REFLECTION_WARNING`, Constant Field Values

#### INSTANCE_TRAVERSE_BY_REFLECTION_WARNING

    public static final short INSTANCE_TRAVERSE_BY_REFLECTION_WARNING

Makes gc emit reflection-based traversion warning for every traversed object instead of only once per class. A potential reflection-based traversion occurs whenever an object is traversed that neither implements `Traverseproc`, nor is annotated with the `Untraversable`-annotation.

See Also:
  `setJythonGCFlags(short)`, `getJythonGCFlags()`, `addJythonGCFlags(short)`, `removeJythonGCFlags(short)`, `SUPPRESS_TRAVERSE_BY_REFLECTION_WARNING`, Constant Field Values

#### USE_PY_WRITE_DEBUG

    public static final short USE_PY_WRITE_DEBUG

In Jython one usually uses `Py.writeDebug` for debugging output. However that method is only verbose if an appropriate verbose-level was set. In CPython it is enough to set gc-`DEBUG` flags to get gc-messages, no matter what overall verbose level is selected. This flag tells Jython to use `Py.writeDebug` for debugging output. If it is not set (default-case), gc-debugging output (if gc-`VERBOSE` or -`DEBUG` flags are set) is directly written to `System.err`.

See Also:
  `setJythonGCFlags(short)`, `getJythonGCFlags()`, `addJythonGCFlags(short)`, `removeJythonGCFlags(short)`, Constant Field Values

#### VERBOSE_COLLECT

    public static final short VERBOSE_COLLECT

Enables collection-related verbose-output.

See Also:
  `setJythonGCFlags(short)`, `getJythonGCFlags()`, `addJythonGCFlags(short)`, `removeJythonGCFlags(short)`, Constant Field Values

#### VERBOSE_WEAKREF

    public static final short VERBOSE_WEAKREF

Enables weakref-related verbose-output.

See Also:
  `setJythonGCFlags(short)`, `getJythonGCFlags()`, `addJythonGCFlags(short)`, `removeJythonGCFlags(short)`, Constant Field Values

#### VERBOSE_DELAYED

    public static final short VERBOSE_DELAYED

Enables delayed finalization related verbose-output.

See Also:
  `setJythonGCFlags(short)`, `getJythonGCFlags()`, `addJythonGCFlags(short)`, `removeJythonGCFlags(short)`, Constant Field Values

#### VERBOSE_FINALIZE

    public static final short VERBOSE_FINALIZE

Enables finalization-related verbose-output.

See Also:
  `setJythonGCFlags(short)`, `getJythonGCFlags()`, `addJythonGCFlags(short)`, `removeJythonGCFlags(short)`, Constant Field Values

#### VERBOSE

    public static final short VERBOSE

Bit-combination of the flags `VERBOSE_COLLECT`, `VERBOSE_WEAKREF`, `VERBOSE_DELAYED`, `VERBOSE_FINALIZE`.

See Also:
  `setJythonGCFlags(short)`, `getJythonGCFlags()`, `addJythonGCFlags(short)`, `removeJythonGCFlags(short)`, Constant Field Values

#### DEBUG_STATS

    public static final int DEBUG_STATS

print collection statistics (in Jython scoped on monitored objects)

See Also:
  `set_debug(int)`, `get_debug()`, Constant Field Values

#### DEBUG_COLLECTABLE

    public static final int DEBUG_COLLECTABLE

print collectable objects (in Jython scoped on monitored objects)

See Also:
  `set_debug(int)`, `get_debug()`, Constant Field Values

#### DEBUG_UNCOLLECTABLE

    public static final int DEBUG_UNCOLLECTABLE

print uncollectable objects (in Jython scoped on monitored objects)

See Also:
  `set_debug(int)`, `get_debug()`, Constant Field Values

#### DEBUG_INSTANCES

    public static final int DEBUG_INSTANCES

print instances (in Jython scoped on monitored objects)

See Also:
  `set_debug(int)`, `get_debug()`, Constant Field Values

#### DEBUG_OBJECTS

    public static final int DEBUG_OBJECTS

print other objects (in Jython scoped on monitored objects)

See Also:
  `set_debug(int)`, `get_debug()`, Constant Field Values

#### DEBUG_SAVEALL

    public static final int DEBUG_SAVEALL

save all garbage in gc.garbage (in Jython scoped on monitored objects)

See Also:
  `set_debug(int)`, `get_debug()`, Constant Field Values

#### DEBUG_LEAK

    public static final int DEBUG_LEAK

Bit-combination of the flags `DEBUG_COLLECTABLE`, `DEBUG_UNCOLLECTABLE`, `DEBUG_INSTANCES`, `DEBUG_OBJECTS`, `DEBUG_SAVEALL`.

See Also:
  `set_debug(int)`, `get_debug()`, Constant Field Values

#### gcRecallTime

    public static long gcRecallTime

#### garbage

    public static PyList garbage

list of uncollectable objects

#### postFinalizationTimeOut

    public static long postFinalizationTimeOut

#### __doc__

    public static final String __doc__

See Also:
  Constant Field Values

#### __name__

    public static final String __name__

See Also:
  Constant Field Values

#### __doc__enable

    public static final PyString __doc__enable

#### __doc__disable

    public static final PyString __doc__disable

#### __doc__isenabled

    public static final PyString __doc__isenabled

#### __doc__collect

    public static final PyString __doc__collect

#### __doc__get_count

    public static final PyString __doc__get_count

#### __doc__set_debug

    public static final PyString __doc__set_debug

#### __doc__get_debug

    public static final PyString __doc__get_debug

#### __doc__set_thresh

    public static final PyString __doc__set_thresh

#### __doc__get_thresh

    public static final PyString __doc__get_thresh

#### __doc__get_objects

    public static final PyString __doc__get_objects

#### __doc__is_tracked

    public static final PyString __doc__is_tracked

#### __doc__get_referrers

    public static final PyString __doc__get_referrers

#### __doc__get_referents

    public static final PyString __doc__get_referents

### Constructor Detail

#### gc

    public gc()

### Method Detail

#### writeDebug

    public static void writeDebug(String type,
                  String msg)

Works like `Py.writeDebug(String, String)`, but prints to `Py.writeDebug(String, String)` (i.e. subject to Jython's verbose level) or directly to `System.err`, according to `USE_PY_WRITE_DEBUG`.

See Also:
  `USE_PY_WRITE_DEBUG`, `Py.writeDebug(String, String)`

#### delayedFinalizationEnabled

    public static boolean delayedFinalizationEnabled()

#### registerForDelayedFinalization

    public static void registerForDelayedFinalization(PyObject ob)

#### registerPreFinalizationProcess

    public 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 by `FinalizeTrigger`s; to care for other finalizers these must call `gc.notifyPreFinalization()` before anything else is done and `gc.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 in `collect()`.

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 and `gc.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

    public static void registerPreFinalizationProcess(Runnable process,
                                      int index)

See doc of `registerPreFinalizationProcess(Runnable)`.

#### indexOfPreFinalizationProcess

    public static int indexOfPreFinalizationProcess(Runnable process)

#### unregisterPreFinalizationProcess

    public static boolean unregisterPreFinalizationProcess(Runnable process)

#### unregisterPreFinalizationProcessAfterNextRun

    public static void unregisterPreFinalizationProcessAfterNextRun(Runnable process)

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

    public 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 by `FinalizeTrigger`s; to care for other finalizers these must call `gc.notifyPreFinalization()` before anything else is done and `gc.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 in `collect()`).

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 and `gc.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

    public static void registerPostFinalizationProcess(Runnable process,
                                       int index)

See doc of `registerPostFinalizationProcess(Runnable)`.

#### indexOfPostFinalizationProcess

    public static int indexOfPostFinalizationProcess(Runnable process)

#### unregisterPostFinalizationProcess

    public static boolean unregisterPostFinalizationProcess(Runnable process)

#### unregisterPostFinalizationProcessAfterNextRun

    public static void unregisterPostFinalizationProcessAfterNextRun(Runnable process)

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

    public static void monitorObject(PyObject ob)

#### monitorObject

    public static void monitorObject(PyObject ob,
                     boolean initString)

#### getMonitorReference

    public static org.python.modules.gc.WeakReferenceGC getMonitorReference(PyObject ob)

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

    public static boolean isMonitored(PyObject ob)

#### unmonitorObject

    public static boolean unmonitorObject(PyObject ob)

#### 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 a `short` 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 to `garbage`.
`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 traversion.
`SUPPRESS_TRAVERSE_BY_REFLECTION_WARNING` - Suppress warnings for PyObjects that neither implement `Traverseproc` nor are marked as `Untraversable`.
`USE_PY_WRITE_DEBUG` - uses `Py.writeDebug(String, String)` for debugging output instead of directly writing to `System.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

    public static void notifyFinalize(PyObject finalized)

Do not call this method manually. It should only be called by `FinalizeTrigger`.

#### 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 `Py.NotImplementedError`.

Throws:
  `org.python.core.Py.NotImplementedError`

#### isenabled

    public static boolean isenabled()

Always returns `true` in Jython.

#### collect

    public static int collect(int generation)

The generation parameter is only for compatibility with CPython `gc.collect()` 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()`

#### collect

    public static int collect()

If no objects are monitored, this just delegates to `System.gc()` and returns `UNKNOWN_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:
  `UNKNOWN_COUNT`, `collect(int)`

#### get_count

    public static PyObject get_count()

Not supported by Jython. Throws `Py.NotImplementedError`.

Throws:
  `org.python.core.Py.NotImplementedError`

#### set_debug

    public static void set_debug(int flags)

Copied from CPython-doc:
Set the garbage collection debugging flags. Debugging information is written to `System.err`.
flags is an `int`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).

See Also:
  `DEBUG_STATS`, `DEBUG_COLLECTABLE`, `DEBUG_UNCOLLECTABLE`, `DEBUG_INSTANCES`, `DEBUG_OBJECTS`, `DEBUG_SAVEALL`, `DEBUG_LEAK`

#### get_debug

    public static int get_debug()

Copied from CPython-doc:
Get the garbage collection debugging flags.

#### set_threshold

    public static void set_threshold(PyObject[] args,
                     String[] kwargs)

Not supported by Jython. Throws `Py.NotImplementedError`.

Throws:
  `org.python.core.Py.NotImplementedError`

#### get_threshold

    public static PyObject get_threshold()

Not supported by Jython. Throws `Py.NotImplementedError`.

Throws:
  `org.python.core.Py.NotImplementedError`

#### get_objects

    public static PyObject get_objects()

Not supported by Jython. Throws `Py.NotImplementedError`.

Throws:
  `org.python.core.Py.NotImplementedError`

#### get_referrers

    public static PyObject get_referrers(PyObject[] args,
                         String[] kwargs)

Only works reliably if `monitorGlobal` 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 traversion 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

    public static PyObject get_referents(PyObject[] args,
                         String[] kwargs)

Only works reliably if all objects in args properly implement the Traverseproc mechanism (unless reflection-based traversion 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

    public static PyObject is_tracked(PyObject[] args,
                      String[] kwargs)

`is_tracked` is - in Jython case - interpreted in the sense that `gc.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 in `test_gc.py`.

#### markCyclicObjects

    public 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.

#### findCyclicObjects

    public static Set<PyObject> findCyclicObjects(PyObject start)

Return objects that are reachable from start AND can reach start, thus participate in a cycle with start. Returns `null` if start does not participate in any cycle.

#### traverse

    public static int traverse(PyObject ob,
               Visitproc visit,
               Object arg)

Does its best to traverse the given `PyObject` `ob`. It exploits both `Traverseproc.traverse(Visitproc, Object)` and `TraverseprocDerived.traverseDerived(Visitproc, Object)`. If `ob` neither implements `Traverseproc` nor `Traverseproc` and is not annotated with `Untraversable`, reflection-based traversion via `traverseByReflection(Object, Visitproc, Object)` may be attempted according to `DONT_TRAVERSE_BY_REFLECTION`.

See Also:
  `Traverseproc.traverse(Visitproc, Object)`, `TraverseprocDerived.traverseDerived(Visitproc, Object)`, `DONT_TRAVERSE_BY_REFLECTION`, `Untraversable`, `traverseByReflection(Object, Visitproc, Object)`

#### traverseByReflection

    public static int traverseByReflection(Object ob,
                           Visitproc visit,
                           Object arg)

This method recursively traverses fields of `ob`. If a field is a PyObject, it is passed to `visit`. and recursion ends in that branch. If a field is an array, the elements are checked whether they are PyObjects. `PyObject`-elements are passed to `visit`. 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

    public 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 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 by `ob.getClass()` and with `actual == false`, if cls was obtained as a field-type or component-type of an array.

#### isTraversable

    public static boolean isTraversable(PyObject ob)