• Java JNA (五)—— 释放Memory对象分配的内存


    Java进程的内存包括Java NonHeap空间Java Heap空间Native Heap空间
    JNA中的Memory对象是从Native Heap中分配空间。但java的GC是针对Java Heap空间设计的,当Java Heap空间不足时会触发GC,但Native Heap空间不够却不会触发GC。
    所以,当Java Heap占用空间不大时,并不会GC掉Memory对象,也就不会执行finalize()方法从而释放分配的Native Heap空间。
    参考: http://ayufox.iteye.com/blog/723896

    Memory中的finalize()方法:

     /** Properly dispose of native memory when this object is GC'd. */
        @Override
        protected void finalize() {
            dispose();
        }
     
        /** Free the native memory and set peer to zero */
        protected synchronized void dispose() {
            try {
                free(peer);
            } finally {
                peer = 0;
                allocatedMemory.remove(this);
            }
        }
     
     protected static void free(long p) {
            // free(0) is a no-op, so avoid the overhead of the call
            if (p != 0) {
                Native.free(p);
            }
        }
    

    其中,Native.free()方法如下:

        /**
         * Call the real native free
         * @param ptr native address to be freed; a value of zero has no effect,
         * passing an already-freed pointer will cause pain.
         */
        public static native void free(long ptr);
    

    Pointer类中的方法:

     	/** Read the native peer value.  Use with caution. */
        public static long nativeValue(Pointer p) {
            return p == null ? 0 : p.peer;
        }
     
        /** Set the native peer value.  Use with caution. */
        public static void nativeValue(Pointer p, long value) {
            p.peer = value;
        }
    

    由上面的源码可知,当Memory被GC掉时,会自动去释放分配的直接内存(前提是要执行GC)。为了避免过多的使用Memory分配直接内存而导致直接内存空间不足,可以手动释放掉Memory分配的内存,方法如下:

    Pointer p = new Memory(1024 * 1024);
    long peer = Pointer.nativeValue(p);
    Native.free(peer);//手动释放内存
    Pointer.nativeValue(p, 0);//避免Memory对象被GC时重复执行Nativ.free()方法
    

    如果不调用最后一行代码

    Pointer.nativeValue(p, 0);
    

    则在GC时,会报错,并且程序异常退出。

  • 相关阅读:
    C# Dictionary几种遍历方式
    Android 代码中文字在手机上显示乱码问题解决方法
    【Android学习5】Clean 之后R文件丢失
    【android学习4】Eclipse中Clean作用
    Java基础语法(练习)
    Java基础语法(自定义类、ArrayList集合)
    Java基础语法(方法)
    Java基础语法(数组)
    Java基础(Scanner、Random、流程控制语句)
    Java基础(变量、运算符)
  • 原文地址:https://www.cnblogs.com/gmhappy/p/11864010.html
Copyright © 2020-2023  润新知