在 Dalvik 中的两个进程之间共享内存

Posted

技术标签:

【中文标题】在 Dalvik 中的两个进程之间共享内存【英文标题】:Share memory between two processes in Dalvik 【发布时间】:2013-02-27 22:06:40 【问题描述】:

我创建了一个 android 服务,它向应用程序公开一个接口以接受相机帧字节数组。该服务使用本机库来处理此相机帧并返回有关相机帧的一些数据。目标是能够实时处理相机预览帧。

问题 - 我的 AIDL 文件有一个名为 initFrame(in byte[] frame)的 API。每当我从应用程序(在单独的进程中运行)调用此 API 时,都会出现异常 - TransactionTooLargeException

这是因为字节数组的大小 > 1MB,并且绑定器事务缓冲区的大小固定为 1MB。即使大小限制更大,复制大缓冲区以进行实时处理也是非常低效的。

问题 - android 中有没有办法在两个 dalvik 进程之间共享内存来帮助解决问题?我查看了MemoryFile,但目前看来 MemoryFile 只能用于在使用隐藏 API 的进程之间共享内存。

【问题讨论】:

【参考方案1】:

对于这种类型的事务,我会在 2 个进程之间使用套接字连接。双方可以根据需要流式传输数据和缓冲区,而不会占用大量资源。对于您的服务来说,侦听套接字并让客户端连接到套接字并发送数据应该相对容易。

【讨论】:

【参考方案2】:

看看 ashmem 子系统,它是一个共享内存分配器,类似于 POSIX SHM,但具有不同的行为并具有更简单的基于文件的 API。

也许这就是你要找的东西:

int ashmem_create_region(const char *name, size_t size);
int ashmem_set_prot_region(int fd, int prot);
int ashmem_pin_region(int fd, size_t offset, size_t len);
int ashmem_unpin_region(int fd, size_t offset, size_t len);
int ashmem_get_size_region(int fd);

这是在system/core/include/cutils/ashmem.h 中定义的。

【讨论】:

我查看了 ashmem,但是如何在我的 JAVA 应用程序中使用 ashmem?我不想用 NDK 给应用程序带来负担。 这是一个应用程序,展示了如何使用 ashmem 在不同应用程序之间/本地 C 和 Java 之间进行 mmap。 github.com/vecio/AndroidIPC【参考方案3】:

如果您能够修改Android系统,您可以扩大交易规模。 Binder 事务缓冲区有一个有限的固定大小,目前为 1Mb

ProcessState.cpp中有一个参数

#define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2))

请尝试增加此值。

如果您无法做到这一点,请尝试将您的数据分成多个事务。

此外,您还可以采取其他 IPC 机制,例如使用本机代码来使用 system/core/include/cutils/ashmem.h 中的 ashmem。这并不难。据我所知,有些厂商使用ashmem在一些没有binder驱动支持的内核上实现binder事务。你也可以使用socket。

【讨论】:

增加这个值有什么风险(如果有的话)?

以上是关于在 Dalvik 中的两个进程之间共享内存的主要内容,如果未能解决你的问题,请参考以下文章

Linux进程间通信--共享内存

共享内存的实现

进程通信之共享内存

Linux 进程间通信 --共享内存

linux进程间的通信之 共享内存

Linux进程间通信——使用共享内存