Android系統匿名共享記憶體Ashmem(Anonymous Shared Memory)簡要介紹和學習計劃
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類的建構函式來看看這兩種使用方法:
- 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;
- }
- ......
- }
- 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;
- }
- ......
- }
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從註釋中,我們可以看出這兩個建構函式的使用方法,這裡就不再詳述了。兩個建構函式的主要區別是第一個引數,第一種構造方法是以指定的字串呼叫JNI方法native_open來建立一個匿名共享記憶體檔案,從而得到一個檔案描述符,接著就以這個檔案描述符為引數呼叫JNI方法natvie_mmap把這個匿名共享記憶體檔案對映在程式空間中,然後就可以透過這個對映後得到的地址空間來直接訪問記憶體資料了;第二種構造方法是以指定的檔案描述符來直接呼叫JNI方法natvie_mmap把這個匿名共享記憶體檔案對映在程式空間中,然後進行訪問,而這個檔案描述符就必須要是一個匿名共享記憶體檔案的檔案描述符,這是透過一個內部函式isMemoryFile來驗證的,而這個內部函式isMemoryFile也是透過JNI方法呼叫來進一步驗證的。前面所提到的這些JNI方法呼叫,最終都是透過系統執行時庫層進入到核心空間的Ashmem驅動程式中去,不過這裡我們不關心這些JNI方法、系統執行庫層呼叫以及Ashmem驅動程式的具體實現,在接下來的兩篇文章中,我們將會著重介紹,這裡我們只關注MemoryFile這個類的使用方法。fd
is null. * @throws IOException Iffd
does not refer to an existing memory file, * or if the file mode of the existing memory file is more restrictive * thanmode
. * * @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; } ...... }
前面我們說到,我們在這裡舉的例子包含了一個Server端和一個Client端實現,其中, Server端就是透過前面一個建構函式來建立一個匿名共享記憶體檔案,接著,Client端過Binder程式間通訊機制來向Server請求這個匿名共享記憶體的檔案描述符,有了這個檔案描述符之後,就可以透過後面一個建構函式來共享這個記憶體檔案了。
因為涉及到Binder程式間通訊,我們首先定義好Binder程式間通訊介面。Binder程式間通訊機制的相關介紹,請參考前面一篇文章Android程式間通訊(IPC)機制Binder簡要介紹和學習計劃,這裡就不詳細介紹了,直接進入主題。
首先在原始碼工程的packages/experimental目錄下建立一個應用程式工程目錄Ashmem。關於如何獲得Android原始碼工程,請參考在Ubuntu上下載、編譯和安裝Android最新原始碼一文;關於如何在Android原始碼工程中建立應用程式工程,請參考在Ubuntu上為Android系統內建Java應用程式測試Application Frameworks層的硬體服務一文。這裡,工程名稱就是Ashmem了,它定義了一個路徑為shy.luo.ashmem的package,這個例子的原始碼主要就是實現在這裡了。下面,將會逐一介紹這個package裡面的檔案。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/13164110/viewspace-747971/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Android系統匿名共享記憶體Ashmem(Anonymous Shared Memory)簡要介紹和學習計劃 (五)Android記憶體
- Android系統匿名共享記憶體Ashmem(Anonymous Shared Memory)簡要介紹和學習計劃 (四)Android記憶體
- Android系統匿名共享記憶體Ashmem(Anonymous Shared Memory)簡要介紹和學習計劃 (三)Android記憶體
- Android系統匿名共享記憶體Ashmem(Anonymous Shared Memory)簡要介紹和學習計劃 (二)Android記憶體
- Android匿名共享記憶體(Ashmem)原理Android記憶體
- Android系統中的廣播(Broadcast)機制簡要介紹和學習計劃 .AndroidAST
- Dalvik虛擬機器簡要介紹和學習計劃虛擬機
- Android程式間通訊(IPC)機制Binder簡要介紹和學習計劃Android
- ASMM (Auto Shared Memory Manangement) 自動共享記憶體管理ASMNaN記憶體
- ART執行時垃圾收集機制簡要介紹和學習計劃
- Dalvik虛擬機器垃圾收集機制簡要介紹和學習計劃虛擬機
- javascript記憶體管理簡單介紹JavaScript記憶體
- javascript 記憶體使用管理簡單介紹JavaScript記憶體
- 計算機記憶體管理介紹計算機記憶體
- memory儲存引擎 /MySQL記憶體表的特性與使用介紹儲存引擎MySql記憶體
- Linux系統程式設計—共享記憶體之mmapLinux程式設計記憶體
- CUDA記憶體介紹記憶體
- 記憶體回收介紹記憶體
- 【讀書筆記】Android的Ashmem機制學習筆記Android
- 作業系統——記憶體管理學習筆記作業系統記憶體筆記
- jvm堆記憶體和GC簡介JVM記憶體GC
- JVM中記憶體和GC的介紹JVM記憶體GC
- Unix高階程式設計學習筆記--系統呼叫簡介程式設計筆記
- 記憶體管理簡介記憶體
- linux作業系統修改共享記憶體的簡單方法(轉)Linux作業系統記憶體
- [CareerCup] 8.9 An In-memory File System 記憶體檔案系統記憶體
- Linux系統和核心初始化過程簡要介紹(轉)Linux
- Linux系統程式設計之命名管道與共享記憶體Linux程式設計記憶體
- javascript匿名函式簡單介紹JavaScript函式
- Bootstrap速學教程之簡要介紹boot
- STM32記憶體結構介紹和FreeRTOS記憶體分配技巧記憶體
- ros學習檔案系統介紹ROS
- Android WebView Memory Leak WebView記憶體洩漏AndroidWebView記憶體
- Sieve—Android 記憶體分析系統Android記憶體
- MQTT簡要介紹MQQT
- Win10系統GPU共享記憶體怎麼關閉?Win10系統GPU共享記憶體的關閉方法Win10GPU記憶體
- Java記憶體模型 - 簡介Java記憶體模型
- Java記憶體模型簡介Java記憶體模型