android 匿名共享内存 作用,Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划(一)...

在Android系统中,提供了独特的匿名共享内存子系统Ashmem(Anonymous Shared Memory),它以驱动程序的形式实现在内核空间中。它有两个特点,一是能够辅助内存管理系统来有效地管理不再使用的内存块,二是它通过Binder进程间通信机制来实现进程间的内存共享。本文中,我们将通过实例来简要介绍Android系统的匿名共享内存的使用方法,使得我们对Android系统的匿名共享内存机制有一个感性的认识,为进一步学习它的源代码实现打下基础。

Android系统的匿名共享内存子系统的主体是以驱动程序的形式实现在内核空间的,同时,在系统运行时库层和应用程序框架层提供了访问接口,其中,在系统运行时库层提供了C/C++调用接口,而在应用程序框架层提供了Java调用接口。这里,我们将直接通过应用程序框架层提供的Java调用接口来说明匿名共享内存子系统Ashmem的使用方法,毕竟我们在Android开发应用程序时,是基于Java语言的,而实际上,应用程序框架层的Java调用接口是通过JNI方法来调用系统运行时库层的C/C++调用接口,最后进入到内核空间的Ashmem驱动程序去的。

我们在这里举的例子是一个名为Ashmem的应用程序,它包含了一个Server端和一个Client端实现,其中,Server端是以Service的形式实现的,在这里Service里面,创建一个匿名共享内存文件,而Client是一个Activity,这个Activity通过Binder进程间通信机制获得前面这个Service创建的匿名共享内存文件的句柄,从而实现共享。在Android应用程序框架层,提供了一个MemoryFile接口来封装了匿名共享内存文件的创建和使用,它实现在frameworks/base/core/java/android/os/MemoryFile.java文件中。下面,我们就来看看Server端是如何通过MemoryFile类来创建匿名共享内存文件的以及Client是如何获得这个匿名共享内存文件的句柄的。

在MemoryFile类中,提供了两种创建匿名共享内存的方法,我们通过MemoryFile类的构造函数来看看这两种使用方法:

publicclassMemoryFile

{

......

/**

* Allocates a new ashmem region. The region is initially not purgable.

*

* @param name optional name for the file (can be null).

* @param length of the memory file in bytes.

* @throws IOException if the memory file could not be created.

*/

publicMemoryFile(String name,intlength)throwsIOException {

mLength = length;

mFD = native_open(name, length);

mAddress = native_mmap(mFD, length, PROT_READ | PROT_WRITE);

mOwnsRegion =true;

}

/**

* Creates a reference to an existing memory file. Changes to the original file

* will be available through this reference.

* Calls to {@link #allowPurging(boolean)} on the returned MemoryFile will fail.

*

* @param fd File descriptor for an existing memory file, as returned by

*        {@link #getFileDescriptor()}. This file descriptor will be closed

*        by {@link #close()}.

* @param length Length of the memory file in bytes.

* @param mode File mode. Currently only "r" for read-only access is supported.

* @throws NullPointerException if fd is null.

* @throws IOException If fd does not refer to an existing memory file,

*         or if the file mode of the existing memory file is more restrictive

*         than mode.

*

* @hide

*/

publicMemoryFile(FileDescriptor fd,intlength, String mode)throwsIOException {

if(fd ==null) {

thrownewNullPointerException("File descriptor is null.");

}

if(!isMemoryFile(fd)) {

thrownewIllegalArgumentException("Not a memory file.");

}

mLength = length;

mFD = fd;

mAddress = native_mmap(mFD, length, modeToProt(mode));

mOwnsRegion =false;

}

......

}

publicclassMemoryFile

{

......

/**

* Allocates a new ashmem region. The region is initially not purgable.

*

* @param name optional name for the file (can be null).

* @param length of the memory file in bytes.

* @throws IOException if the memory file could not be created.

*/

publicMemoryFile(String name,intlength)throwsIOException {

mLength = length;

mFD = native_open(name, length);

mAddress = native_mmap(mFD, length, PROT_READ | PROT_WRITE);

mOwnsRegion =true;

}

/**

* Creates a reference to an existing memory file. Changes to the original file

* will be available through this reference.

* Calls to {@link #allowPurging(boolean)} on the returned MemoryFile will fail.

*

* @param fd File descriptor for an existing memory file, as returned by

*        {@link #getFileDescriptor()}. This file descriptor will be closed

*        by {@link #close()}.

* @param length Length of the memory file in bytes.

* @param mode File mode. Currently only "r" for read-only access is supported.

* @throws NullPointerException if fd is null.

* @throws IOException If fd does not refer to an existing memory file,

*         or if the file mode of the existing memory file is more restrictive

*         than mode.

*

* @hide

*/

publicMemoryFile(FileDescriptor fd,intlength, String mode)throwsIOException {

if(fd ==null) {

thrownewNullPointerException("File descriptor is null.");

}

if(!isMemoryFile(fd)) {

thrownewIllegalArgumentException("Not a memory file.");

}

mLength = length;

mFD = fd;

mAddress = native_mmap(mFD, length, modeToProt(mode));

mOwnsRegion =false;

}

......

}

public class MemoryFile

{

......

/**

* Allocates a new ashmem region. The region is initially not purgable.

*

* @param name optional name for the file (can be null).

* @param length of the memory file in bytes.

* @throws IOException if the memory file could not be created.

*/

public MemoryFile(String name, int length) throws IOException {

mLength = length;

mFD = native_open(name, length);

mAddress = native_mmap(mFD, length, PROT_READ | PROT_WRITE);

mOwnsRegion = true;

}

/**

* Creates a reference to an existing memory file. Changes to the original file

* will be available through this reference.

* Calls to {@link #allowPurging(boolean)} on the returned MemoryFile will fail.

*

* @param fd File descriptor for an existing memory file, as returned by

* {@link #getFileDescriptor()}. This file descriptor will be closed

* by {@link #close()}.

* @param length Length of the memory file in bytes.

* @param mode File mode. Currently only "r" for read-only access is supported.

* @throws NullPointerException if fd is null.

* @throws IOException If fd does not refer to an existing memory file,

* or if the file mode of the existing memory file is more restrictive

* than mode.

*

* @hide

*/

public MemoryFile(FileDescriptor fd, int length, String mode) throws IOException {

if (fd == null) {

throw new NullPointerException("File descriptor is null.");

}

if (!isMemoryFile(fd)) {

throw new IllegalArgumentException("Not a memory file.");

}

mLength = length;

mFD = fd;

mAddress = native_mmap(mFD, length, modeToProt(mode));

mOwnsRegion = false;

}

......

}

从注释中,我们可以看出这两个构造函数的使用方法,这里就不再详述了。两个构造函数的主要区别是第一个参数,第一种构造方法是以指定的字符串调用JNI方法native_open来创建一个匿名共享内存文件,从而得到一个文件描述符,接着就以这个文件描述符为参数调用JNI方法natvie_mmap把这个匿名共享内存文件映射在进程空间中,然后就可以通过这个映射后得到的地址空间来直接访问内存数据了;第二种构造方法是以指定的文件描述符来直接调用JNI方法natvie_mmap把这个匿名共享内存文件映射在进程空间中,然后进行访问,而这个文件描述符就必须要是一个匿名共享内存文件的文件描述符,这是通过一个内部函数isMemoryFile来验证的,而这个内部函数isMemoryFile也是通过JNI方法调用来进一步验证的。前面所提到的这些JNI方法调用,最终都是通过系统运行时库层进入到内核空间的Ashmem驱动程序中去,不过这里我们不关心这些JNI方法、系统运行库层调用以及Ashmem驱动程序的具体实现,在接下来的两篇文章中,我们将会着重介绍,这里我们只关注MemoryFile这个类的使用方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Android C的共享内存是一种高效的IPC机制,它允许不同的进程共享内存区域,从而实现数据共享和数据传输。在Android系统中,使用共享内存有两种基本方法:POSIX共享内存Ashmem。 POSIX共享内存(shm_open系统调用)是基于文件的IPC机制,它可以在不同的进程间共享文件系统中的内存块。在使用该方法时,首先创建并打开一个共享内存对象以便其他进程能够在其中写入或读取数据。与普通文件不同的是,该对象可以被多个进程同时访问,从而实现内存共享和数据传输。 AshmemAndroid专有的共享内存机制,它通过匿名内存映射(mmap系统调用)来创建共享内存,使多个进程可以共享相同的内存区域。在使用Ashmem时,首先在一个进程中分配一块内存区域,并将其标记为共享内存。其他进程可以通过Binder接口来获取该内存区域所对应的Ashmem文件描述符,并进一步映射内存区域,以便共享数据。 正如所见,Android C的共享内存机制提供了一种高效的IPC方法,可以在不同的进程之间实现数据共享和数据传输。但是由于共享内存存在并发访问、内存泄露等问题,因此在应用中使用时需要格外小心。 ### 回答2: Android C共享内存是一种在Android系统中用于不同进程间共享数据的机制。在多进程应用程序中,进程之间共享数据允许各个进程共同访问数据,从而提高系统的整体性能。C共享内存实现了这种数据共享的方式,允许多个进程可以同步地访问相同的内存区域,从而实现数据共享。 C共享内存操作需要用到管道和信号量等Linux中的IPC技术。进程可以通过信号量来控制对共享内存区域的访问,从而实现数据同步。同时,通过管道机制,同步地向共享内存区域写入和读出数据。在Android开发中,通常会使用NDK库和底层C语言来实现共享内存操作,可以对共享内存区域进行读写操作和管理。 通常情况下,在Android的多进程应用程序中,可以使用C共享内存来实现不同进程之间的数据共享,从而提高应用程序的整体性能和响应速度。C共享内存也可以被用于进程间的通信,例如在游戏和音视频应用程序中,可以使用共享内存来实现不同进程的交互与协作。总的来说,Android C共享内存提供了一种能够优化应用程序性能和提高用户体验的底层机制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值