Android RAM页面大小?

6
我希望优化InputStream的读取,所以我认为最好有一个大小为RAM页面的byte[]缓冲区。
有没有一种方法(可能是静态的)来知道它的大小?
编辑:
最终我使用NDK和JNI成功了,我在C中编写了以下代码:
#include <jni.h>
#include <unistd.h>

jlong Java_it_masmil_tests_TestsActivity_pageSize(JNIEnv* env, jobject javaThis) {
    return sysconf(_SC_PAGE_SIZE);
}

其中:

  • it.masmil.tests是包名
  • TestsActivity是类名
  • pageSize是方法名
  • env和javaThis是两个必需参数(在某些情况下很有用)

我使用NDK编译了该文件,然后在Java中编写了以下代码:

static {
    System.loadLibrary("clibrary");
}
private native long pageSize();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    long page = pageSize();
}

其中:

  • clibrary是我使用NDK创建的库的名称
  • pageSize是在C文件中声明的方法的名称
3个回答

8

页面大小由Linux (内核)定义,您可以通过调用libc (bionic)的sysconf(_SC_PAGESIZE)函数通过JNI获取它。由于Android运行在Linux上并且大多数情况下是ARM系统,因此您可以假定页面大小为4k。

#include <unistd.h>
long sz = sysconf(_SC_PAGESIZE);

然而,在Java/C中很难获得这种对齐方式。也就是说,即使您请求一个4k块,也没有人保证它将被4k对齐。

如果您需要在Linux上获取4k对齐的块,则应使用mmap,该函数保证按页面大小对齐。


我从未使用过它,我尝试了一下,但是不知道如何让它工作...(尝试此链接http://patriot.net/~tvalesky/jninative.html) - Massimo

1
您可以一般地假设页面大小为4KB或更大(能够处理较小页面大小的MMU已经几乎绝迹)。此外,如果您没有方法将缓冲区对齐到精确的页面边界,那么它很可能仍然跨越两个页面。
最后,所有这些努力都是完全浪费的 - 如果MMU遭受一两次页面缺失,实际I/O成本的数量级将完全超出。甚至不太可能恢复添加的初始化成本,更不用说您花在实现上的所有时间了。
您提供了过度热衷于优化的完美例子,如果您只是分析应用程序并从最常调用的方法中削减一两个周期,您可以花费所有这些时间以获得更大的回报(例如)。

我的目的并不是过于热衷,而是正在开发一个库,可用于Android应用程序中的内存操作,因此我需要知道如何获取该信息。此外,我使用了这个示例来学习如何使用NDK。如何使用这些信息是那些将使用此库的人的工作,我的目的只是获得该值,而不是使用它... - Massimo
我是在回答你明确表达的意图:“我想优化InputStream的读取”。“可用于内存操作的库”并不自动使得这个努力变得合理,请再次阅读我的整个答案——你基本上没有实际的方法来满足利用你对页面大小的知识的所有条件。即使你能够做到,回报也不会证明投入的工作量是值得的。我严格地看待成本与回报,而不是使用抽象的理性化来说服自己它是值得的。 - Durandal

-2

很难相信添加JNI等功能真的能够回报成本。就像其他人一样使用4096或8192。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接