Does this technique prevent Java from garbage collecting?

stevendesu :

Colt McAnlis did a wonderfully entertaining video on preventing the JavaScript garbage collector from slowing down applications

The gist of it is as follows:

  1. When the app loads, instantiate a pool of unused objects / classes that your app may need at some point in the future.
  2. When you want to instantiate a new object, instead find an object of the appropriate type in your pool that is unused, grab it, and set its properties.
  3. Utilize this object, instead.
  4. When you're done with it, mark it as "unused" so future methods can utilize it.

My question is if this methodology would also work with the Java garbage collector, or if it's trickier to circumvent and it would just end up scanning your entire heap or something.

This is mostly a theoretical / curiosity thing. I don't have any apps in development that depend on circumventing garbage collection.

Stephen C :

It would "work" in a sense. But it is not recommended, because there are some significant problems.

  1. If you implement this incorrectly, it is a memory leak. The problem is that the "pool" needs to keep a reference to all of its objects. This prevents then from being garbage collected. But if the application fails to always mark objects as "unused" when it is done with them (e.g. a bug), those objects remains "in use" for ever.

    (If you try to mitigate this using something like Reference objects, you end up using more space, and placing more load on the GC.)

  2. When the GC does run, it has to traverse all of the objects in the pool, and all of their dependent objects as well. That is more work than if the objects had been allowed to die. (Young unreachable objects don't need to be scanned at all.)

  3. After a few GC cycles, the objects in your pool will be tenured, because they are long lived. That means that they will tend to cause short-term dependent objects that might otherwise be collectable to be retained until the old heap is collected. Also, reference assignments to fields of tenured objects may be more expensive, and may make young space collections take longer (because of old -> young references).

Note that the kind of object pools you are talking about are typically proposed / done to mitigate excessive GC pauses in an application. In a typical modern JVM, there are GCs that are specifically designed to minimize the pauses. Low pause collectors are a better alternative for solving this problem in most Java applications. (An exception would highly interactive games where any kind of "lagging" is simply unacceptable.)

There are other reasons for using object pools:

  • To deal with objects that are very expensive to initialize.
  • To deal with objects that need to be limited in number.
  • To deal with objects associated with external resources that need to be properly managed.

Examples include thread pools, database connection pools, and HTTP connection pools (under the hood in typical HTTP client-side libraries). These are definitely beneficial in the appropriate circumstances.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=94374&siteId=1