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时,会报错,并且程序异常退出。

Java JNA (五)—— 释放Memory对象分配的内存的更多相关文章

  1. java中基本类型封装对象所占内存的大小(转)

    这是一个程序,java中没有现成的sizeof的实现,原因主要是java中的基本数据类型的大小都是固定的,所以看上去没有必要用sizeof这个关键字. 实现的想法是这样的:java.lang.Runt ...

  2. EXE中释放DLL中分配的内存

    在DLL中分配的内存,如果到其调用者中释放,可能会出现CRASH的情况,其原因在于: 在DLL中的Code Generation如果是采用了MT(静态加载LIBCRTD.LIB)在该库中维护了一个al ...

  3. free()函数释放一段分配的内存之陷阱

    朋友们对malloc函数应该是比较熟悉了,此函数功能是分配一段内存地址,并且将内存地址给一个指针变量,最后记得再调用free函数释放这段内存地址就可以了,标准的流程对吧,好像没什么问题.但是按照此标准 ...

  4. java高级用法之:JNA中的Memory和Pointer

    目录 简介 Pointer 特殊的Pointer:Opaque Memory 总结 简介 我们知道在native的代码中有很多指针,这些指针在JNA中被映射成为Pointer.除了Pointer之外, ...

  5. Atitit. 。Jna技术与 解决 java.lang.Error: Invalid memory access

    Atitit. .Jna技术与 解决 java.lang.Error: Invalid memory access 1. 原因与解决1 2. jNA (这个ms sun 的)1 3. Code1 4. ...

  6. JVM虚拟机-了解Java堆中对象分配、布局和访问的全过程

    目录 前言 对象的创建 类加载检查 分配内存 内存空间分配方式 指针碰撞 空闲列表 并发时的内存分配 同步处理:CAS 本地线程分配缓冲:TLAB 初始化零值 设置对象头 执行 init 方法 对象的 ...

  7. Java 关于创建String对象过程的内存分配

    一.String s = "abc"  和 String s = new String("abc") 的区别 1.String s = "abc&qu ...

  8. java 笔记(1)-—— JVM基础,内存数据,内存释放,垃圾回收,即时编译技术JIT,高精度类型

    1.java中5个存放数据的地方: (1).寄存器(Registers):位于CPU内部,是速度最快的存储区,但是数量和容量有限.在java中不能直接操作寄存器. (2).栈(Stack):栈位于通用 ...

  9. 记一次java程序out of memory问题

    在一个比较大批量的pdf转String项目中遇到了:java.lang.OutOfMemoryError: Java heap space错误 第一反应肯定是程序没有写好,大量循环时没有把程序中没有用 ...

随机推荐

  1. Quick BI的宝藏工具——交叉表

    对于普通的表格展示数据,相信大家都非常熟悉了,今天给大家介绍的是BI领域的分析利器-交叉表,这个在BI分析场景中使用占比最多的分析利器.通过交叉表对数据的承载和管理,用户可以一目了然地分析出各种场景指 ...

  2. JSP实现大文件上传和下载

    javaweb上传文件 上传文件的jsp中的部分 上传文件同样可以使用form表单向后端发请求,也可以使用 ajax向后端发请求 1.通过form表单向后端发送请求 <form id=" ...

  3. RedHat下使用gcc编译HelloWorld.cpp

    gcc ./HelloWorld.cpp 错误: /tmp/ccZuz3Ca.o:(.eh_frame+0x12): undefined reference to `__gxx_personality ...

  4. Linux用户和用户组指令

    1.创建用户 >useradd username 创建用户 >passwd username 给用户设置密码 ======================================= ...

  5. linux 文件相关常用命令

    文件或者目录操控命令 1,cd切换目录. 其中- 代表前一个目录 2,mkdir 新建目录. 加上-p参数可以递归创建多级目录 mkdir -p test1/test2/test3 3,rmdir删除 ...

  6. 北风设计模式课程---单一职责原则(Single Responsibility Principle)

    北风设计模式课程---单一职责原则(Single Responsibility Principle) 一.总结 一句话总结: 一个类应该有且只有一个变化的原因:单一职责原则(SRP:Single Re ...

  7. MySQL主从复制 报错处理

    基于GTID的主从复制: 跳过一个事务: SET @@session.gtid_next = '冲突的GTID号';BEGIN;COMMIT; SET gtid_next = 'AUTOMATIC';

  8. 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_05 IO字符流_6_字符输出流写数据的其他方法

    从1开始写写三个字符 最后多了个bcd 写入字符串 字符串的一部分

  9. WPF与DevExpress之——实现类似于安装程序下一步下一步的样式窗体

    话不多说先上图  点击下一步  跳转到第二页  项目准备: 1.DevExpress 19/18/17(三个版本都可以) 2.Vs2019 3..Net framework>4.0 项目结构: ...

  10. C#之委托(二)

    其实在上一篇委托(一)中,创建委托还是太繁琐了点.代码量过多,可能会妨碍我们对代码和逻辑的理解.有些时候可能处理逻辑的代码都笔声明委托的代码要少,这就不可避免的增加了重复代码的量.所以在c#2中极大的 ...