Java直接内存读写的例子

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

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

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

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

Java代码  

  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实例。

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

Java代码  

  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

时间: 2024-10-12 17:04:58

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

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

打算记录两个最简单的FFmpeg进行内存读写的例子.之前的所有有关FFmpeg的例子都是对文件进行操作的.例如<100行代码实现最简单的基于FFMPEG+SDL的视频播放器>播放的是一个视频的文件.而<最简单的基于FFMPEG的转码程序>也是将一个视频文件转换为另一个视频文件.<最简单的基于FFmpeg的视频编码器(YUV编码为H.264)>也是最后编码得到一个H.264视频文件.实际上,并不是所有视频的编码,解码都是针对文件进行处理的.有的时候需要的解码的视频数据在一

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

ffmpeg内存播放解码 目录(?)[+] ===================================================== 最简单的基于FFmpeg的内存读写的例子系列文章列表: 最简单的基于FFmpeg的内存读写的例子:内存播放器 最简单的基于FFmpeg的内存读写的例子:内存转码器 ===================================================== 打算记录两个最简单的FFmpeg进行内存读写的例子.之前的所有有关FFmpe

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

上篇文章记录了一个基于FFmpeg的内存播放器,可以使用FFmpeg读取并播放内存中的数据.这篇文章记录一个基于FFmpeg的内存转码器.该转码器可以使用FFmpeg读取内存中的数据,转码为H.264之后再将数据输出到内存.关于如何从内存读取数据,以及如何将数据输出到内存,可以参考文章: ffmpeg 从内存中读取数据(或将数据输出到内存) FFmpeg读写内存的关键点有2个:1.       初始化自定义的AVIOContext,指定自定义的回调函数.2.       自己写回调函数.注意函数

关Java的内存模型(JMM)

JMM的关键技术点都是围绕着多线程的原子性.可见性和有序性来建立的 一.原子性(Atomicity) 原子性是指一个操作是不可中断的.即使是在多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程干扰. 比如,对于一个静态全局变量int i,两个线程同时对它赋值,线程A给他赋值1,线程B给它赋值为-1.那么不管这2个线程以何种方式.何种步调工作,i的值要么是1,要么是-1.线程A和线程B之间是没有干扰的.这就是原子性的一个特点,不可被中断. 但如果我们不使用int型而使用long型的话,可能

[问题贴]小白请教几个关于Java虚拟机内存分配策略的问题

最近在看周志明所著的<深入理解Java虚拟机>,有几个问题不太明白,希望大家帮我回答一下.先说一下我进行试验的环境: 操作系统:Mac OS X 10.11.6 EI Capitan Java环境: java version "1.8.0_92" Java(TM) SE Runtime Environment (build 1.8.0_92-b14) Java HotSpot(TM) 64-Bit Server VM (build 25.92-b14, mixed mode

如何设置Java虚拟机内存以适应大程序的装载

Java虚拟机对于运行时的程序所占内存是有限制的,当我们的项目或者程序很大时,往往会照成内存溢出. 举个例子: public class SmallTest1 { public static void main(String[] args) { byte[] array = new byte[1024*1024*500]; } } 当定义这样一个500MB的数组时,就会造成JVM内存溢出: 而Java虚拟机默认的程序运行能得到的内存大小是随系统的,由Java的api体系结构中,点击Java: 后

Java虚拟机内存分配详解

简介 了解Java虚拟机内存分布的好处 1.了解Java内存管理的细节,有助于程序员编写出性能更好的程序.比如,在新的线程创建时,JVM会为每个线程创建一个专属的栈 (stack),其栈是先进后出的数据结构,这种方式的特点,让程序员编程时,必须特别注意递归方法要尽量少使用,另外栈的大小也有一定的限制,如果过多 的递归,容易导致stack overflow. 2.了解Java内存管理的细节,一旦内存管理出现问题,有助于找到问题的根本原因所在. 3.了解Java内存管理的内幕,有助于优化JVM,从而

Java的内存泄漏_与C/C++对比(转载总结)

原文网址:http://developer.51cto.com/art/201111/302465.htm Java内存泄露的理解与解决(1) 一般来说内存泄漏有两种情况.一种情况如在C/C++ 语言中的,在堆中的分配的内存,在没有将其释放掉的时候,就将所有能访问这块内存的方式都删掉(如指针重新赋值):另一种情况则是在内存对象已经不需要的时候,还仍然保留着这块内存和它的访问方式(引用).第一种情况,在 Java 中已经由于垃圾回收机制的引入,得到了很好的解决.所以, Java 中的内存泄漏,主要

Android优化-与Java有关-内存

内存优化 Android系统对每个软件所能使用的RAM空间进行了限制(如:Nexus one 对每个软件的内存限制是24M),同时Java语言本身比较消耗内存,dalvik虚拟机也要占用一定的内存空间,所以合理使用内存,彰显出一个程序员的素质和技能. 1) 了解JIT 即时编译(Just-in-time Compilation,JIT),又称动态转译(Dynamic Translation),是一种通过在运行时将字节码翻译为机器码,从而改善字节码编译语言性能的技术.即时编译前期的两个运行时理论是