Grizzly 內存管理

原文鏈接:https://javaee.github.io/grizzly/memory.html#

內存管理概述

Grizzly 2.0引入了一個新的子系統,以改善運行時的內存管理。該子系統由三個主要工件組成:

  • 緩衝區 Buffers
  • 線程本地內存池 Thread local memory pools
  • MemoryManager, 作爲工廠按序使用緩衝區和線程本地池

其主要目的是加快內存分配,並在可能的情況下提供內存重用。
以下各節將詳細描述這些概念。

MemoryManager

MemoryManager 是分配和取消已經分配的 Buffer instance的主要接口:

package org.glassfish.grizzly.memory;

import org.glassfish.grizzly.Buffer;
import org.glassfish.grizzly.monitoring.MonitoringAware;

/**
 * <tt>MemoryManager</tt>, responsible for allocating and releasing memory,
 * required during application runtime.
 * <tt>MemoryManager</tt> implementations work with Grizzly {@link Buffer}s.
 *
 * @see Buffer
 *
 * @author Alexey Stashok
 */
public interface MemoryManager<E extends Buffer>
        extends MonitoringAware<MemoryProbe> {

    /**
     * <p>
     * The default {@link MemoryManager} implementation used by all created builder
     * instances.
     * </p>
     *
     * <p>
     * The default may be changed by one of two methods:
     * <ul>
     *     <li>
     *          Setting the system property {@value MemoryManagerInitializer#DMM_PROP_NAME}
     *          with the fully qualified name of the class that implements the
     *          MemoryManager interface.  Note that this class must be public and
     *          have a public no-arg constructor.
     *     </li>
     *     <li>
     *         Setting the system property {@value DefaultMemoryManagerFactory#DMMF_PROP_NAME}
     *         with the fully qualified name of the class that implements the
     *         {@link org.glassfish.grizzly.memory.DefaultMemoryManagerFactory} interface.
     *         Note that this class must be public and have a public no-arg
     *         constructor.
     *     </li>
     * </ul>
     *
     * </p>
     */
    MemoryManager DEFAULT_MEMORY_MANAGER =
            MemoryManagerInitializer.initManager();

    /**
     * Allocated {@link Buffer} of the required size.
     *
     * @param size {@link Buffer} size to be allocated.
     * @return allocated {@link Buffer}.
     */
    E allocate(int size);

    /**
     * Allocated {@link Buffer} at least of the provided size.
     * This could be useful for usecases like Socket.read(...), where
     * we're not sure how many bytes are available, but want to read as
     * much as possible.
     *
     * @param size the min {@link Buffer} size to be allocated.
     * @return allocated {@link Buffer}.
     */
    E allocateAtLeast(int size);

    /**
     * Reallocate {@link Buffer} to a required size.
     * Implementation may choose the way, how reallocation could be done, either
     * by allocating new {@link Buffer} of required size and copying old
     * {@link Buffer} content there, or perform more complex logic related to
     * memory pooling etc.
     *
     * @param oldBuffer old {@link Buffer} to be reallocated.
     * @param newSize new {@link Buffer} required size.
     * @return reallocated {@link Buffer}.
     */
    E reallocate(E oldBuffer, int newSize);

    /**
     * Release {@link Buffer}.
     * Implementation may ignore releasing and let JVM Garbage collector to take
     * care about the {@link Buffer}, or return {@link Buffer} to pool, in case
     * of more complex <tt>MemoryManager</tt> implementation.
     *
     * @param buffer {@link Buffer} to be released.
     */
    void release(E buffer);
    
    /**
     * Return <tt>true</tt> if next {@link #allocate(int)} or {@link #allocateAtLeast(int)} call,
     * made in the current thread for the given memory size, going to return a {@link Buffer} based
     * on direct {@link java.nio.ByteBuffer}, or <tt>false</tt> otherwise.
     * 
     * @param size
     * @return 
     */
    boolean willAllocateDirect(int size);
}

通常只有一個MemoryManager服務於Grizzly運行時中定義的所有傳輸。可以通過引用MemoryManager接口的靜態成員來獲得此MemoryManager:

MemoryManager DEFAULT_MEMORY_MANAGER = MemoryManagerInitializer.initManager();

然而,可以通過定義系統屬性org.glassfish.grizzly.DEFAULT_MEMORY_MANAGER來定義自定義MemoryManager實現,作爲默認的MemoryManager,
該系統屬性引用要使用的MemoryManager實現的完全限定的類名。請注意,此實現必須具有公共的無參數構造函數,以便運行時正確設置新的默認值。

Grizzly 2.3包含兩個MemoryManager實現:HeapMemoryManager和ByteBufferManager。默認情況下,Grizzly運行時將使用HeapMemoryManager,
但是,如果Grizzly應用程序需要直接ByteBuffer訪問,則可以使用ByteBufferManager。

ByteBufferManager

該ByteBufferManager實施VENDS grizzly 緩衝實例那套JDK的ByteBuffer實例。如果Grizzly應用程序需要直接使用ByteBuffer,則使用此MemoryManager。
應該注意的是,在進行基準測試期間,此 MemoryManager 通常在使用堆緩衝區時需要更多的開銷。因此,如果不需要直接讀取內存,我們建議使用默認的HeapMemoryManager。

HeapMemoryManager

HeapMemoryManager 是默認的 MemoryManager。代替包裝 ByteBuffer 實例,此 MemoryManager 將分配直接包裝字節數組的Buffer實例。
此 MemoryManager 爲 trimming 或 splitting 之類的操作提供更好的性能特徵。

ThreadLocal Memory Pools

ThreadLocal 內存池提供了無需任何同步成本即可分配內存的功能。無論是 ByteBufferManager 和 HeapMemoryManager 使用這些池。請注意,
不需要自定義 MemoryManager 使用此類池,但是,如果該 MemoryManager 實現 ThreadLocalPoolProvider 接口,則必須提供 ThreadLocalPool 實現。
該 ThreadLocalPool 執行將被創建並傳遞給每個通過 Grizzly 管理維持的線程。

Memory Manager and ThreadLocal Memory Pools Working Together

以下提供了使用ThreadLocalPool向MemoryManager分配請求通常如何工作的流程圖:
memory manager and ThreadLocal

緩衝區 Buffers

Grizzly 2.3提供了一些緩衝區,供開發人員在創建應用程序時使用。這些Buffer實現一些功能,這些功能是使用JDK的ByteBuffer時沒有的。

Buffer

該緩衝器本質上是模擬到JDK的字節緩衝區。它提供了以下相同的方法集:

  • 向 Buffer 推入/拉出 (pushing/pulling) 數據。
  • 用於訪問或操縱緩衝區的位置(position),限制(limit)和容量(capacity)的方法。

除了爲ByteBuffer提供熟悉的語義外,還提供以下功能:

  • 分割,修剪和縮小。 splitting, trimming and shrinking
  • 在當前緩衝區之前添加另一個緩衝區的內容。 Prepending another Buffer’s content to the current Buffer.
  • 將緩衝區轉換爲ByteBuffer或ByteBuffer []。 Converting the Buffer to a ByteBuffer or ByteBuffer[].
  • 將緩衝區內容轉換爲字符串。 Converting Buffer content to a String.

請參閱javadocs以獲取有關Buffer的更多詳細信息。

CompositeBuffer

該CompositeBuffer是另一個緩衝區實現它允許附加的緩衝實例。所述CompositeBuffer維護虛擬位置,限制和基於容量緩衝器已所附和可以被視爲簡單的緩衝液的實例。
有關CompositeBuffer的更多詳細信息,請參見javadocs 。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章