【问题标题】:Android RAM page size?Android RAM页面大小?
【发布时间】:2012-11-12 21:32:45
【问题描述】:

我想优化 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和java这是两个强制参数(在某些场合有用)

我用 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 文件中声明的方法的名称

【问题讨论】:

    标签: java android linux


    【解决方案1】:

    页面大小由 Linux(内核)定义,您可以通过 JNI 调用 libc (bionic) 的 sysconf(_SC_PAGESIZE) 来获取它。由于 Android 在 Linux 上运行并且主要在 ARM 系统上运行,因此您可以假设 4k 页面大小。

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

    但是,您不能真正轻松地从 Java/C 中获得这种对齐方式。这意味着即使您要求 4k 块,也没有人保证会是 4k 对齐的。

    如果您在 Linux 上需要一个 4k 对齐的块,您应该使用mmap 保证页面大小对齐。

    【讨论】:

    【解决方案2】:

    您通常可以假设页面大小为 4KB 或更大(可以处理较小页面大小的 MMU 实际上已绝迹)。此外,如果您无法将缓冲区与精确的页面边界对齐,它很可能仍会跨越两个页面。

    最后,所有这些努力都完全白费了——如果 MMU 发生一两次页面丢失,实际 I/O 成本将超过许多数量级。你甚至不可能收回增加的初始化成本,更不用说你花在实现它上的所有时间了。

    你做了一个过分热心优化工作的完美例子,如果你只是对你的应用程序进行分析并在最常调用的方法中减少一两个周期,你可能会花费所有时间来获得更大的回报(例如)。

    【讨论】:

    • 我的并不过分热心,我正在实现一个可用于 Android 应用程序中的内存操作的库,然后我需要知道如何获取该信息。此外,我使用这个示例来学习如何使用 NDK。如何使用这些信息是使用这个库的人的工作,我的目的只是拥有那个价值,而不是使用它......
    • 我在回答您的问题时明确说明了意图:“我想优化 InputStream 的读取”。 “一个可用于内存操作的库”也不会自动将这项工作限定为 reasonable,请再次阅读我的整个答案 - 你基本上没有切实可行的方法来满足所有条件来利用您对页面大小的了解。即使你可以,回报也不能证明投入的工作量是合理的。我严格看待成本与回报,而不是使用抽象的合理化来说服自己值得。
    【解决方案3】:

    很难相信添加JNI等真的会收回成本。像其他人一样使用 4096 或 8192。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-28
      • 2010-10-10
      • 1970-01-01
      • 1970-01-01
      • 2015-12-12
      • 2021-04-07
      相关资源
      最近更新 更多