共享内存对应应用开发的意义
对熟知UNIX系统应用开发的程序员来说,IPC(InterProcess Communication)机制是非常熟悉的,IPC基本包括共享内存、信号灯操作、消息队列、信号处理等部分,是开发应用中非常重要的必不可少的工具。其中共享内存IPC机制的关键,对于数据共享、系统快速查询、动态配置、减少资源耗费等均有独到的优点。
对应UNIX系统来说,共享内存分为一般共享内存和映像文件共享内存两种,而对应Windows,实际上只有映像文件共享内存一种。所以JAVA应用中,也是只能创建映像文件共享内存。
在JAVA语言中,基本上没有提及共享内存这个概念,但是,在某一些应用中,共享内存确实非常有用,例如采用JAVA语言的分布式应用系统中,存在着大量的分布式共享对象,很多时候需要查询这些对象的状态,以查看系统是否运行正常或者了解这些对象的目前的一些统计数据和状态。如果采用网络通信的方式,显然会增加应用的额外负担,也增加了一些不必要的应用编程。而如果采用共享内存的方式,则可以直接通过共享内存查看对象的状态数据和统计数据,从而减少了一些不必要的麻烦。
共享内存的使用有如下几个特点:
1)可以被多个进程打开访问;
2)读写操作的进程在执行读写操作时其他进程不能进行写操作;
3)多个进程可以交替对某一共享内存执行写操作;
4)一个进程执行了内存的写操作后,不影响其他进程对该内存的访问。同时其他进程对更新后的内存具有可见性;
5)在进程执行写操作时如果异常退出,对其他进程写操作禁止应自动解除;
6)相对共享文件,数据访问的方便性和效率。
另外,共享内存的使用上有如下情况:
1)独占的写操作,相应有独占的写操作等待队列。独占的写操作本身不会发生数据的一致性问题。
2)共享的写操作,相应有共享的写操作等待队列。共享的写操作则要注意防止发生数据的一致性问题。
3)独占的读操作,相应有共享的读操作等待队列。
4)共享的读操作,相应有共享的读操作等待队列。
在jdk1.4中提供的类MappedByteBuffer为我们实现共享内存提供了较好的方法。该缓冲区实际上是一个磁盘文件的内存映像。二者的变化将保持同步,即内存数据发生变化会立刻反映到磁盘文件中,这样会有效的保证共享内存的实现。
将共享内存和磁盘文件建立联系的是文件通道类:FileChannel。该类的加入是JDK为了统一对外部设备(文件、网络接口等)的访问方法,并且加强了多线程对同一文件进行存取的安全性。例如读写操作统一成read和write。这里只是用它来建立共享内存用,它建立了共享内存和磁盘文件之间的一个通道。
什么是Java内存映射文件/IO
内存映射文件是一种允许Java程序直接从内存访问的特殊文件。通过将整个文件或者文件的一部分映射到内存中、操作系统负责获取页面请求和写入文件,应用程序就只需要处理内存数据,这样可以实现非常快速的IO操作。用于内存映射文件的内存在Java的堆空间以外。Java中的java.nio包支持内存映射文件,可以使用MappedByteBuffer来读写内存。
java中共享内存的应用:
1.永久对象的配置
2.共享数据的查询
存映射文件的优缺点
可能内存映射IO的主要优势是性能,内存映射文件比通过普通的IO来访问文件要快,这对于繁忙的电子交易系统来说非常重要。内存映射IO另外一个优势是能够加载普通方式无法访问的大文件,实验表明内存映射IO在大文件处理中表现得更好;但缺点是有增加页面错误(page fault)的可能,因为操作系统仅仅加载一部分文件到内存中,如果被请求的页面不在内存中那就会导致一个页面错误。大多数主流操作系统如Windows, Unix, Solaris和其他类Unix的操作系统都支持内存映射IO,在64位架构下,你几乎可以将任何文件映射到内存中并直接使用Java访问。另外一个优势是这些文件能够共享,在进程间提供共享内存,而且比普通的基于loopback接口的Socket要快10倍。
总结
下面快速总结一下Java内存映射文件和IO
1)Java语言通过java.nio包支持内存映射文件和IO。
2)内存映射文件用于对性能要求高的系统中,如繁忙的电子交易系统
3)使用内存映射IO你可以将文件的一部分加载到内存中
4)如果被请求的页面不在内存中,内存映射文件会导致页面错误
5)将一个文件区间映射到内存中的能力取决于内存的可寻址范围。在32位机器中,不能超过4GB,即2^32比特。
6)Java中的内存映射文件比流IO要快(译注:对于大文件而言是对的,小文件则未必)
7)用于加载文件的内存在Java的堆内存之外,存在于共享内存中,允许两个不同进程访问文件。顺便说一下,这依赖于你用的是direct还是non-direct字节缓存。
8) 读写内存映射文件是操作系统来负责的,因此,即使你的Java程序在写入内存后就挂掉了,只要操作系统工作正常,数据就会写入磁盘。
9)Direct字节缓存比non-direct字节缓存性能要好
10 )不要经常调用MappedByteBuffer.force()方法,这个方法强制操作系统将内存中的内容写入硬盘,所以如果你在每次写内存映射文件后都调用force()方法,你就不能真正从内存映射文件中获益,而是跟disk IO差不多。
11)如果电源故障或者主机瘫痪,有可能内存映射文件还没有写入磁盘,意味着可能会丢失一些关键数据。
12)MappedByteBuffer和文件映射在缓存被GC之前都是有效的。sun.misc.Cleaner可能是清除内存映射文件的唯一选择。
相关推荐
### Java共享内存并行编程 #### 1. 引言 随着计算机技术的发展,特别是多核处理器的普及,高效利用多核架构成为提高程序性能的关键因素之一。Java作为一种跨平台的语言,不仅在Web开发、企业级应用等领域有着广泛...
java进程间通讯机制代码----RMI、共享内存、Socket、管道,等方式,每种方法我都讲了原理和例子程序,很有参考意义。在网上很难找到的。
标题“IPC.rar_IPC_java i_java ipc_java共享内存_共享内存”以及描述“IPC共享内存,文件映射编程,实现原理详解”都指向了一个核心主题:Java中的进程间通信(IPC)以及如何利用共享内存进行数据交换。在这个话题中...
首先,我们要知道在Unix-like系统(如Linux)中,共享内存主要通过`sys/shm.h`头文件中的函数来操作,比如`shmget`用于创建共享内存,`shmat`用于将共享内存附加到进程地址空间,`shmdt`用于解除共享内存的附加,...
VS2005 C# 共享内存 源代码
共享内存是一种在多进程或线程之间实现高效通信的技术,它允许不同的进程访问同一块物理内存,从而直接交换数据。这个"共享内存示范代码"压缩包包含了一系列与创建和使用共享内存相关的C++源文件,如TestSMDlg.cpp、...
在Java中,可以通过`java.nio.MappedByteBuffer`类来实现共享内存功能,这被称为内存映射文件(Memory-Mapped File,MMF)。 `MappedByteBuffer`是NIO中的一种特殊缓冲区,它将文件的一部分映射到内存中,使得文件...
堆内存是Java中的全局共享区域,用于存储所有的对象实例和数组。当通过`new`关键字创建一个新的对象时,其实际的数据结构和属性值都在堆中分配。由于堆内存是所有线程共享的,因此对象实例的创建和访问需要考虑线程...
在Java层,使用`ParcelFileDescriptor`可以创建一个指向共享内存的文件描述符,然后通过Binder传递。在C++层,`Parcel`对象提供了`readFileDescriptor()`和`writeFileDescriptor()`方法来处理文件描述符。 4. **...
总之,Java内存模型是Java编程中的一个基础性话题,它定义了Java程序在多线程环境下关于数据共享、线程通信和同步的规则和约束。深入掌握Java内存模型对于编写高效且正确的Java多线程程序有着不可忽视的作用。程序员...
这是Java程序的主要内存区域之一,所有对象实例都位于这里。堆内存是由JVM动态管理的,它负责对象的创建、存储以及垃圾回收。 **特点:** - 堆内存是线程共享的,所有线程都可以访问堆中的对象。 - 堆内存的分配...
这也是Java相对于C++等语言更加占用内存的原因之一。 Java内存分配策略包括静态存储分配、栈式存储分配和堆式存储分配。静态存储分配在编译时就确定了变量的内存需求,栈式分配在运行时按需分配,而堆式分配则处理...
标题中的“基于共享内存的HashMap”指的是在多进程或多线程环境中,使用共享内存作为存储机制的哈希映射数据结构。哈希映射(HashMap)是一种常用的数据结构,它通过键值对(key-value pairs)的方式快速存取数据,...
Java采用的是共享内存模型,线程间通过共享变量来隐式通信。 Java内存模型定义了线程和主内存之间的抽象关系,即所有共享变量存储在主内存中,每个线程都有自己的本地内存,用于存储共享变量的副本。本地内存并不是...
Java虚拟机(JVM)内存结构是理解Java应用程序性能和内存管理的关键。本文将详细介绍JVM内存的不同组件,包括它们的功能和重要性。 首先,Java虚拟机规范中的内存管理主要涉及Runtime Data Area,这是一个用于存储...
总之,掌握如何在Java中获取和管理JVM内存大小,是每一个Java开发者都应具备的基本技能之一。通过合理利用`Runtime`类提供的API和灵活调整JVM的启动参数,可以有效地提升应用程序的性能和用户体验。
此外,Java内存模型(JMM)也非常重要,它定义了线程之间的共享变量如何交互,以及在并发环境下如何保证内存可见性和一致性。熟悉 volatile、synchronized 和 final 关键字的作用,可以帮助我们编写出正确处理并发的...
Java内存模型,简称JMM(Java Memory Model),是Java编程语言规范的一部分,它定义了程序中各个线程如何访问和修改共享变量,以及如何确保数据的一致性。深入理解Java内存模型对于编写高效的并发程序至关重要。本文...