Class JNIMemoryManager


  • public final class JNIMemoryManager
    extends java.lang.Object
    Manages the native memory that Ferry objects allocate and destroy.

    Native memory isn't nicely garbage collected like Java memory is, and managing it can be challenging to those not familiar with it. Ferry is all about making native objects behave nicely in Java, and in order to have Ferry make objects look like Java objects, the JNIMemoryManager does some black magic to ensure native memory is released behind the scenes.

    To do this by default Ferry uses a Robust mechanism for ensuring native memory is released, but that comes at the expense of some Speed. This approach is tunable though.

    if you run a Java Profiler and see your application is spending a lot of time copying on incremental collections, or you need to eke out a few more microseconds of speed, or you're bored, then it's time to experiment with different JNIMemoryManager.MemoryModel configurations that Ferry supports by calling setMemoryModel(MemoryModel). This is pretty advanced stuff though, so be warned.

    Read JNIMemoryManager.MemoryModel for more.

    Author:
    aclarke
    See Also:
    JNIMemoryManager.MemoryModel
    • Method Detail

      • collect

        public static void collect()
        A convenience way to call getMgr().gc().

        Really somewhat mis-named, as this will cause us to free any native memory allocated by ferry, but won't cause us to walk our own internal heap -- that's only done on allocation.

      • setMinimumReferencesToCache

        public void setMinimumReferencesToCache​(int minimumReferencesToCache)
        Sets the minimum number of references to cache.

        The JNIMemoryManager needs to cache weak references to allocated Ferry object. This setting controls the minimum size of that cache.

        Parameters:
        minimumReferencesToCache - Minimum number of references to cache.
        Throws:
        java.lang.IllegalArgumentException - if <= 0
      • setExpandIncrement

        public void setExpandIncrement​(double expandIncrement)
        Get the percentage value we will increment the reference cache by if we need to expand it.
        Parameters:
        expandIncrement - A percentage we will increment the reference cache by if we need to expand it.
        Throws:
        java.lang.IllegalArgumentException - if <= 0
      • setShrinkFactor

        public void setShrinkFactor​(double shrinkFactor)
        Set the percentage value we will shrink the reference cache by when we determine shrinking is possible.

        If we decide to shrink, the amount we shrink the cache by is getExpandIncrement()*getShrinkFactor().

        Parameters:
        shrinkFactor - The shrink percentage.
        Throws:
        java.lang.IllegalArgumentException - if shrinkFactor <=0 or >= 100.
        See Also:
        setExpandIncrement(double)
      • setMaxFreeRatio

        public void setMaxFreeRatio​(double maxFreeRatio)
        Sets the maximum ratio of free space we'll allow without trying to shrink the memory manager heap.
        Parameters:
        maxFreeRatio - The maximum amount (0 < maxFreeRatio < 100) of free space.
      • getMaxFreeRatio

        public double getMaxFreeRatio()
        Get the maximum ratio of free space we'll allow in a memory manager heap before trying to shrink on the next collection.
        Returns:
        the ratio of free space
        See Also:
        setMaxFreeRatio(double)
      • setMinFreeRatio

        public void setMinFreeRatio​(double minFreeRatio)
        Sets the minimum ratio of free space to total memory manager heap size we'll allow before expanding the heap.
        Parameters:
        minFreeRatio - The minimum free ratio.
      • getMinFreeRatio

        public double getMinFreeRatio()
        Gets the minimum ratio of free space to total memory manager heap size we'll allow before expanding the heap.
        Returns:
        The minimum free ratio.
        See Also:
        setMinFreeRatio(double)
      • getNumPinnedObjects

        public long getNumPinnedObjects()
        Get the number of Ferry objects we believe are still in use.

        This may be different than what you think because the Java garbage collector may not have collected all objects yet.

        Also, this method needs to walk the entire ferry reference heap, so it can be expensive and not accurate (as the value may change even before this method returns). Use only for debugging.

        Returns:
        number of ferry objects in use.
      • dumpMemoryLog

        public void dumpMemoryLog()
        Dump the contents of our memory cache to the log.

        This method requires a global lock in order to run so only use for debugging.

      • setMemoryDebugging

        public void setMemoryDebugging​(boolean value)
        Set whether the JNIMemoryManager should cause objects to be allocated with debugging information. This is false by default as it causes a slight performance hit per-allocation.

        If true, then each allocation after setting to true will remember the class of each object allocated, and the unique java hash code (Object.hashCode()) of each object allocated. Then in calls to dumpMemoryLog(), those classes and hash values will also be printed.

        Parameters:
        value - true to turn on memory debugging; false to turn it off.
      • finalize

        public void finalize()
        A finalizer for the memory manager itself. It just calls internal garbage collections and then exits.
        Overrides:
        finalize in class java.lang.Object
      • gc

        public void gc()
        Do a Ferry Garbage Collection.

        This takes all Ferry objects that are no longer reachable and deletes the underlying native memory. It is called every time you allocate a new Ferry object to ensure Ferry is freeing up native objects as soon as possible (rather than waiting for the potentially slow finalizer thread). It is also called via a finalizer on an object that is referenced by the Ferry'ed object (that way, the earlier of the next Ferry allocation, or the finalizer thread, frees up unused native memory). Lastly, you can use startCollectionThread() to start up a thread to call this automagically for you (and that thread will exit when your JVM exits).

      • gc

        public void gc​(boolean doSweep)
        Does a Ferry Garbage Collection, and also sweeps our internal JNIReference heap to remove any lightweight references we may have left around.
        Parameters:
        doSweep - if true, we sweep the heap. This involves a global lock and so should be used sparingly.
      • startCollectionThread

        public void startCollectionThread()
        Starts a new Ferry collection thread that will wake up whenever a memory reference needs clean-up from native code.

        This thread is not started by default as Ferry calls gc() internally whenever a new Ferry object is allocated. But if you're caching Ferry objects and hence avoiding new allocations, you may want to call this to ensure all objects are promptly collected.

        This call is ignored if the collection thread is already running.

        The thread can be stopped by calling stopCollectionThread(), and will also exit if interrupted by Java.

      • stopCollectionThread

        public void stopCollectionThread()
        Stops the Ferry collection thread if running. This does nothing if no collection thread is running.
      • flush

        public final void flush()
        Internal Only. Immediately frees all active objects in the system. Do not call unless you REALLY know what you're doing.