在Hotspot JVM上,我们能够直接对内存进行读写操作。该类的allocateMemory方法用于申请分配内存,putAddress和getAddress方法用于对直接内存进行读写。

本文将通过sun.misc.Unsafe给出一个直接读写内存的例子。

注意:这只是一个例子,只是用来验证通过sun.misc.Unsafe来实现直接读写内存的可能性。但是,这样做并没有安全保证,而且稍微有点疏忽将可能导致JVM崩溃。

Unsafe类的三个方法:allocateMemory,putAddress和getAddress如下:

  1. /**
  2. * Fetches a native pointer from a given memory address.  If the address is
  3. * zero, or does not point into a block obtained from {@link
  4. * #allocateMemory}, the results are undefined.
  5. *
  6. * <p> If the native pointer is less than  bits wide, it is extended as
  7. * an unsigned number to a Java long.  The pointer may be indexed by any
  8. * given byte offset, simply by adding that offset (as a simple integer) to
  9. * the long representing the pointer.  The number of bytes actually read
  10. * from the target address maybe determined by consulting {@link
  11. * #addressSize}.
  12. *
  13. * @see #allocateMemory
  14. */
  15. public native long getAddress(long address);
  16. /**
  17. * Stores a native pointer into a given memory address.  If the address is
  18. * zero, or does not point into a block obtained from {@link
  19. * #allocateMemory}, the results are undefined.
  20. *
  21. * <p> The number of bytes actually written at the target address maybe
  22. * determined by consulting {@link #addressSize}.
  23. *
  24. * @see #getAddress(long)
  25. */
  26. public native void putAddress(long address, long x);
  27. /// wrappers for malloc, realloc, free:
  28. /**
  29. * Allocates a new block of native memory, of the given size in bytes.  The
  30. * contents of the memory are uninitialized; they will generally be
  31. * garbage.  The resulting native pointer will never be zero, and will be
  32. * aligned for all value types.  Dispose of this memory by calling {@link
  33. * #freeMemory}, or resize it with {@link #reallocateMemory}.
  34. *
  35. * @throws IllegalArgumentException if the size is negative or too large
  36. *         for the native size_t type
  37. *
  38. * @throws OutOfMemoryError if the allocation is refused by the system
  39. *
  40. * @see #getByte(long)
  41. * @see #putByte(long, byte)
  42. */
  43. public native long allocateMemory(long bytes);

1. long allocateMemory(long bytes) 
申请分配内存 
2. long getAddress(long address) 和void putAddress(long address, long x) 
对直接内存进行读写。

因为Unsafe这个类的访问是受限的,只有rt.jar中的类才能使用Unsafe的功能,它的构造方法是私有的,所以,我们不能通过new来创建实例。但是,可以通过反射的方法来获取Unsafe实例。

下面就是一个直接访问内存的一个例子:

  1. import java.lang.reflect.Field;
  2. import sun.misc.Unsafe;
  3. public class DirectMemoryAccess {
  4. public static void main(String[] args) {
  5. /*
  6. * Unsafe的构造函数是私有的,不能通过new来获得实例。
  7. *
  8. *  通过反射来获取
  9. */
  10. Unsafe unsafe = null;
  11. Field field = null;
  12. try {
  13. field = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
  14. /*
  15. * private static final Unsafe theUnsafe = new Unsafe();
  16. *
  17. * 因为field的修饰符为 private static final,
  18. * 需要将setAccessible设置成true,否则会报java.lang.IllegalAccessException
  19. */
  20. field.setAccessible(true);
  21. unsafe = (Unsafe) field.get(null);
  22. } catch (SecurityException e) {
  23. // TODO Auto-generated catch block
  24. e.printStackTrace();
  25. } catch (NoSuchFieldException e) {
  26. // TODO Auto-generated catch block
  27. e.printStackTrace();
  28. } catch (IllegalArgumentException e) {
  29. // TODO Auto-generated catch block
  30. e.printStackTrace();
  31. } catch (IllegalAccessException e) {
  32. // TODO Auto-generated catch block
  33. e.printStackTrace();
  34. }
  35. long oneHundred = 100;
  36. byte size = 1;
  37. /*
  38. * 调用allocateMemory分配内存
  39. */
  40. long memoryAddress = unsafe.allocateMemory(size);
  41. /*
  42. * 将100写入到内存中
  43. */
  44. unsafe.putAddress(memoryAddress, oneHundred);
  45. /*
  46. * 内存中读取数据
  47. */
  48. long readValue = unsafe.getAddress(memoryAddress);
  49. System.out.println("Val : " + readValue);
  50. }
  51. }

输出结果: 
Val : 100

如果,想要查阅Unsafe的源代码,请参考下面的链接. 
http://www.docjar.com/html/api/sun/misc/Unsafe.java.html

原文 转自 :http://blog.csdn.net/joe_007/article/details/38964407

Java直接内存读写的例子的更多相关文章

  1. 最简单的基于FFmpeg的内存读写的例子:内存转码器

    ===================================================== 最简单的基于FFmpeg的内存读写的例子系列文章列表: 最简单的基于FFmpeg的内存读写的 ...

  2. 最简单的基于FFmpeg的内存读写的例子:内存播放器

    ===================================================== 最简单的基于FFmpeg的内存读写的例子系列文章列表: 最简单的基于FFmpeg的内存读写的 ...

  3. (转)最简单的基于FFmpeg的内存读写的例子:内存播放器

    ffmpeg内存播放解码 目录(?)[+] ===================================================== 最简单的基于FFmpeg的内存读写的例子系列文章 ...

  4. java中常见的内存泄露的例子

    JAVA 中的内存泄露     Java中的内存泄露,广义并通俗的说,就是:不再会被使用的对象的内存不能被回收,就是内存泄露.     Java中的内存泄露与C++中的表现有所不同.     在C++ ...

  5. 沉淀再出发:java的文件读写

    沉淀再出发:java的文件读写 一.前言 对于java的文件读写是我们必须使用的一项基本技能,因此了解其中的原理,字节流和字符流的本质有着重要的意义. 二.java中的I/O操作 2.1.文件读写的本 ...

  6. 深入理解Java虚拟机内存模型

    前言 本文中部分内容引用至<深入理解Java虚拟机:JVM高级特性与最佳实践(第2版)>第12章,如果有兴趣可自行深入阅读,文末放有书籍PDF版本连接. 一.物理机中的并发 物理机遇到的并 ...

  7. 深入理解JVM(③)学习Java的内存模型

    前言 Java内存模型(Java Memory Model)用来屏蔽各种硬件和操作系统的内存访问差异,这使得Java能够变得非常灵活而不用考虑各系统间的兼容性等问题.定义Java内存模型并非一件容易的 ...

  8. Java对象内存布局

    本文转载自Java对象内存布局 导语 首先直接抛出问题 Unsafe.getInt(obj, fieldOffset)中的fieldOffset是什么, 类似还有compareAndSwapX(obj ...

  9. 全网最硬核 Java 新内存模型解析与实验单篇版(不断更新QA中)

    个人创作公约:本人声明创作的所有文章皆为自己原创,如果有参考任何文章的地方,会标注出来,如果有疏漏,欢迎大家批判.如果大家发现网上有抄袭本文章的,欢迎举报,并且积极向这个 github 仓库 提交 i ...

随机推荐

  1. [转帖]MyCat教程【简单介绍】

    MyCat教程[简单介绍] 2019-10-15 10:27:23 波波烤鸭 阅读数 618 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. ...

  2. ASP.NET Core四大部件

    四大部件 (WebHost,Startup,launchSettings,wwwroot) WebHost 简单理解是一个socket, https://www.cnblogs.com/neverc/ ...

  3. (6)Spring Boot web开发 --- 错误处理页面

    文章目录 处理时间(`Date`)类型 thymeleaf 页面拼接字符串 映射路径占位符 使用 put.delete 方法 错误处理机制 处理时间(Date)类型 Spring Boot 进行参数绑 ...

  4. centos 6.10 oracle 19c安装

    centos 7以下版本安装oracle 19c 问题较多,centos 以上版本没有任何问题.记录如下. hosts文件,否则图形界面无法启动 127.0.0.1 localhost localho ...

  5. Python socket编程 (2)--实现文件验证登入

    可以实现从客户端输入账号和密码然后发送到服务器进行验证,实现用户登入校正操作. 服务器: import socket import json server = socket.socket() serv ...

  6. vue的安装配置与项目创建

    1,安装vue必须先安装node.js.  --------去官网安装node.js 因为npm依赖node.js环境,使用npm的时候需要安装node.js.安装node.js的时候npm会默认安装 ...

  7. Asp.Net 加载不同项目程序集

    我们做项目时有时候不想添加别的项目的引用,但是那个项目又必须在 Global 中进行注册 最常见的就是插件机制,参考: https://shazwazza.com/post/Developing-a- ...

  8. C#使用任务并行库(TPL)

    TPL(Task Parallel Library) 任务并行库 (TPL) 是 System.Threading和 System.Threading.Tasks 命名空间中的一组公共类型和 API. ...

  9. wstngfw中配置freeradius

    wstngfw中配置freeradius Radius为各种网络设备和服务提供了一个认证来源. Radius认证常用于***.入网门户.交换机.路由器和防火墙.Radius认证比在网络上的不同设备跟踪 ...

  10. js的变量类型

    参考网址:https://www.cnblogs.com/focusxxxxy/p/6390536.html (讲的蛮好得,图文并茂,我下面只是总结下) 一:ECMAScirpt 变量的两种数据类型 ...