and cannot rely on class invariants (as they may refer to other objects that have already been finalized). Slow finalizers may delay other finalizers. Exceptions within finalizers generally cannot be handled, because the finalizer is run in an unspecified environment, and may be either ignored or cause uncontrolled program termination. Finalizers may reference and accidentally finalize live objects, violating program invariants. Finalizers may cause synchronization issues, even in otherwise sequential (single-threaded) programs, when finalization is done in a separate threads. Finalizers may cause deadlocks if synchronization mechanisms such as locks are used, due to not being run in a specified order and possibly being run concurrently. Finalizers that are run during program termination cannot rely on the usual runtime environment, and thus may fail due to incorrect assumptions – for this reason finalizers are often not run during termination. Further, finalizers may fail to run due to objects remaining reachable beyond when they are expected to be garbage, either due to programming errors or due to unexpected reachability. For example, when Python catches an exception (or an exception is not caught in interactive mode), it keeps a reference to the stack frame where the exception was raised, which keeps objects referenced from that stack frame alive. In Java, finalizers in a superclass can also slow down garbage collection in a subclass, as the finalizer can potentially refer to fields in the subclass, and thus the field cannot be garbage collected until the following cycle, once the finalizer has run. This can be avoided by using composition over inheritance. Resource management A common anti-pattern is to use finalizers to release resources, by analogy with the Resource Acquisition Is Initialization (RAII) idiom of C++: acquire a resource in the initializer (constructor), and release it in the finalizer (destructor). This does not work, for a number of reasons. Most basically, finalizers may never be called, and even if called, may not be called in a timely manner – thus using finalizers to release resources will generally cause resource leaks. Further, finalizers are not called in a prescribed order, while resources often need to be released in a specific order, frequently the opposite order in which they were acquired. Also, as finalizers are called at the discretion of the garbage collector, they will often only be called under managed memory pressure (when there is little managed memory available), regardless of resource pressure – if