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; }