【问题标题】:Native shared library loaded to slow in Android在 Android 中加载的本机共享库变慢
【发布时间】:2013-02-04 10:51:41
【问题描述】:

我在 libs/armeabi 文件夹中放置了一个共享库。它是使用加载的

System.loadLibrary("library_name.so");

库的大小约为 3MB。加载时间很长。它有时会持续近 20 秒。它阻止了我的 GUI。我试图将System.loadLibrary("library_name.so"); 放在不同的线程中,但我的 GUI 仍然被阻止。我知道其他应用程序使用更大的 .so 文件,但加载时间并没有那么大。可能是什么问题?

编辑

3MB 是调试版本的大小。发布版本大约是 800KB,但问题是一样的。一些附加信息:

  • .so 包含我的两个循环连接的 c++ 库
  • 运行arm-linux-androideabi-nm -D -C -g library_name.so会显示很多函数和变量
  • 我不再使用LOCAL_WHOLE_STATIC_LIBRARIES
  • 这里是使用arm-linux-androideabi-readelf-tool得到的section headers表:
Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al

  [ 0]                   NULL            00000000 000000 000000 00      0   0  0

  [ 1] .dynsym           DYNSYM          00000114 000114 00b400 10   A  2   1  4

  [ 2] .dynstr           STRTAB          0000b514 00b514 015b0c 00   A  0   0  1

  [ 3] .hash             HASH            00021020 021020 004d1c 04   A  1   0  4

  [ 4] .rel.dyn          REL             00025d3c 025d3c 006e98 08   A  1   0  4

  [ 5] .rel.plt          REL             0002cbd4 02cbd4 000468 08   A  1   6  4

  [ 6] .plt              PROGBITS        0002d03c 02d03c 0006b0 00  AX  0   0  4

  [ 7] .text             PROGBITS        0002d6f0 02d6f0 08e6e0 00  AX  0   0  8

  [ 8] .ARM.extab        PROGBITS        000bbdd0 0bbdd0 00bad0 00   A  0   0  4

  [ 9] .ARM.exidx        ARM_EXIDX       000c78a0 0c78a0 005b80 08  AL  7   0  4

  [10] .rodata           PROGBITS        000cd420 0cd420 005cc0 00   A  0   0  4

  [11] .data.rel.ro.loca PROGBITS        000d46d8 0d36d8 0006e4 00  WA  0   0  4

  [12] .fini_array       FINI_ARRAY      000d4dbc 0d3dbc 000008 00  WA  0   0  4

  [13] .init_array       INIT_ARRAY      000d4dc4 0d3dc4 00009c 00  WA  0   0  4

  [14] .data.rel.ro      PROGBITS        000d4e60 0d3e60 00384c 00  WA  0   0  8

  [15] .dynamic          DYNAMIC         000d86ac 0d76ac 000100 08  WA  2   0  4

  [16] .got              PROGBITS        000d87ac 0d77ac 000854 00  WA  0   0  4

  [17] .data             PROGBITS        000d9000 0d8000 000648 00  WA  0   0  8

  [18] .bss              NOBITS          000d9648 0d8648 047271 00  WA  0   0  8

  [19] .comment          PROGBITS        00000000 0d8648 000026 01  MS  0   0  1

  [20] .note.gnu.gold-ve NOTE            00000000 0d8670 00001c 00      0   0  4

  [21] .ARM.attributes   ARM_ATTRIBUTES  00000000 0d868c 00002d 00      0   0  1

  [22] .shstrtab         STRTAB          00000000 0d86b9 0000d8 00      0   0  1

【问题讨论】:

  • 库中有多少种方法?您如何向 JNI 注册它们(通过RegisterNatives 或通过给它们提供Java_ 名称)?
  • @fadden 我有 5 个导出函数。它们是使用 RegisterNatives() 注册的。这些方法使用我的 c++ 库中的函数。也许问题可能是整个 c++ 库都包含在我的 .so 文件中?
  • @fadden 我使用了 ausln 的回答中建议的工具。它表明注册了很多功能。我认为问题的出现是因为我正在使用 LOCAL_WHOLE_STATIC_LIBRARIES 并且没有它就无法构建我的项目

标签: java android-ndk java-native-interface shared-libraries


【解决方案1】:

问题是某些构造函数中的静态初始化需要很长时间才能完成

【讨论】:

    【解决方案2】:

    尝试减少共享库中导出函数的数量。你可以使用

    arm-linux-androideabi-nm -D -C -g library_name.so
    

    并检查该列表是否不必要地长,并删除您不使用的列表(将它们声明为静态)。你可以通过$man nm查阅nm的手册,了解如何使用和解读。

    如果您需要使用大量函数,请使用 RegisterNatives() 注册您的函数,而不是依赖名称修改和查找 - 这就是您为函数命名时所做的,例如 Java_your_path_YourClass_yourFunction

    你也可以尝试strip (arm-linux-androideabi-strip) 你的库,如果它有符号的话。

    为避免阻塞 UI,您可以尝试在其他线程中尽早加载共享库并等待它。

    如果公开静态库不是我最终想要的,我不会使用 LOCAL_WHOLE_STATIC_LIBRARIES。

    LOCAL_WHOLE_STATIC_LIBRARIES

    • 这些是您希望包含在模块中且不允许链接器从中删除死代码的静态库。
    • 如果您想将静态库添加到共享库并让静态库的内容从共享库中公开,这非常有用。

    尝试解决该问题,而不是解决一些构建问题。

    【讨论】:

    • 我有 5 个导出函数。它们是使用 RegisterNatives() 注册的。我应该在哪里使用这个arm-linux-androideabi-nm -D -C -g library_name.so
    • 不运行怎么知道导出的函数有多少?
    • 你可以在ndk中找到那个nm。
    • 没有。你应该用 nm 检查 so 文件。
    • 运行这个工具后我得到了很多数据。在前面提到的这 5 个函数中,我使用了我的 c++ 库中的函数。如果不设置LOCAL_WHOLE_STATIC_LIBRARIES,我就无法构建我的项目。我认为这是造成问题的原因
    猜你喜欢
    • 1970-01-01
    • 2019-02-10
    • 1970-01-01
    • 1970-01-01
    • 2012-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多