java 直接内存

android 内存结构 :

dalvik(jvm)内存---navtive men 两部分。

这个概念相信有经验的开发人员都会知道。

java虚拟机分配到的内存是有限的,根据手机不同,大小不一,但也不是很大。处理吃内存的图片视频很小心。

JNI帮助下可以利用系统内存处理很多事情(豁然开朗)。

除了使用JNI,java本身也有很多实现也是基于系统内存的。

直接内存概念:

    不是JVM运行时内存,也不是JVM定义的内存区域,就是堆外单独的一块内存区域。

    例如:NIO(new input/output),基于通道与缓冲区结合的I/O方式,可以用native函数库直接堆外分配内存,通过一个存                储在堆中的DirectByteBuffer对象作为这块内存的引用进行操作,这样能在一些场景中提高性能。

实例:

    /**
     * Allocates a new direct byte buffer.
     *
     * <p> The new buffer's position will be zero, its limit will be its
     * capacity, its mark will be undefined, and each of its elements will be
     * initialized to zero.  Whether or not it has a
     * {@link #hasArray backing array} is unspecified.
     *
     * @param  capacity
     *         The new buffer's capacity, in bytes
     *
     * @return  The new byte buffer
     *
     * @throws  IllegalArgumentException
     *          If the <tt>capacity</tt> is a negative integer
     */
    public static ByteBuffer allocateDirect(int capacity) {
        if (capacity < 0) {
            throw new IllegalArgumentException("capacity < 0: " + capacity);
        }

        DirectByteBuffer.MemoryRef memoryRef = new DirectByteBuffer.MemoryRef(capacity);
        return new DirectByteBuffer(capacity, memoryRef);
    }

MenoryRef方法源码和解释:

       // Reference to original DirectByteBuffer that held this MemoryRef. The field is set
        // only for the MemoryRef created through JNI NewDirectByteBuffer(void*, long) function.
        // This allows users of JNI NewDirectByteBuffer to create a PhantomReference on the
        // DirectByteBuffer instance that will only be put in the associated ReferenceQueue when
        // the underlying memory is not referenced by any DirectByteBuffer instance. The
        // MemoryRef can outlive the original DirectByteBuffer instance if, for example, slice()
        // or asReadOnlyBuffer() are called and all strong references to the original DirectByteBuffer
        // are discarded.
        final Object originalBufferObject;

        MemoryRef(int capacity) {
            VMRuntime runtime = VMRuntime.getRuntime();
            buffer = (byte[]) runtime.newNonMovableArray(byte.class, capacity + 7);
            allocatedAddress = runtime.addressOf(buffer);
            // Offset is set to handle the alignment: http://b/16449607
            offset = (int) (((allocatedAddress + 7) & ~(long) 7) - allocatedAddress);
            isAccessible = true;
            isFreed = false;
            originalBufferObject = null;
        }
原文地址:https://www.cnblogs.com/mamamia/p/10045028.html