首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android 11 -用于本机C++库的C++占用60+秒,在Android 10及以下版本上运行得非常快。

Android 11 -用于本机C++库的C++占用60+秒,在Android 10及以下版本上运行得非常快。
EN

Stack Overflow用户
提问于 2020-10-28 15:37:11
回答 1查看 1.5K关注 0票数 7

在我们基于游戏引擎cocos2d-x的Android游戏应用程序中,大部分代码都是用C++编写的,从Android 11开始,我们就遇到了一个非常奇怪和关键的问题:

当本机库在onLoadNativeLibraries中加载时,现在突然需要60+秒。在Android 11之前,它工作得很好,并在0.2到3秒内完成了装载。现在,当你开始游戏,你有一个60+秒的灰色屏幕。

我们已经知道在60秒失速结束后直接调用JNI_OnLoad

下面是onLoadNativeLibraries函数的代码:

代码语言:javascript
复制
protected void onLoadNativeLibraries()
{
    try
    {
        ApplicationInfo ai = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
        Bundle bundle = ai.metaData;
        String libName = bundle.getString("android.app.lib_name");
        System.loadLibrary(libName); // line of 60 seconds stall
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}

我们已经试过时间分析了,但没有成功。这说明它花了很多时间在这个功能上。此外,通过调试暂停不会带来任何进一步的线索。本机调试器在代码的C++端没有显示任何内容。

有没有人知道为什么会发生这种事,或者我们能想出什么办法?如能提供任何帮助,将不胜感激:)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-10-29 15:08:18

简短回答:

这是谷歌修复的Android 11中的一个bug,但尚未部署。

同时,如果您不关心在程序退出/库卸载时调用库中的静态和thread_local变量析构函数,则将标志-fno-c++-static-destructors传递给编译器。(关于使用clang注释的更细粒度的解决方案,请参见长答案)

我在我的项目(不是cocos2d)中使用了这个标志,没有问题,而且lib的加载速度比以前还要快。

长答案:

不幸的是,这是谷歌团队在android 11 (R)中引入的性能倒退。谷歌这里正在追踪这个问题。

总之,当调用System.loadLibrary()时,系统将使用atexit()为加载库中包含的每个C++全局变量注册一个析构函数。

自从Android 11 (R)之后,这个功能在android上的实现就有了变化

  • 在Q中,__cxa_atexit使用块的链接列表,并在要修改的单个块上调用mprotect两次。
  • 在R中,__cxa_atexit在单个连续的处理程序数组上调用mprotect两次。每个数组条目是2个指针。

当性能是许多C++全局变量时,这种变化会使性能急剧下降,这在cocos2d库中似乎是如此。

谷歌已经实现了修复https://android-review.googlesource.com/c/platform/bionic/+/1464716,但正如问题中所述:

这将不会在Android 11中最早在3月QPR,因为这不是一个安全问题,它将不会是强制性的原始设备制造商实际采取的修补程序。

谷歌团队还建议,通过删除或跳过全局变量上的析构函数,在应用程序级别设置一些解决办法

  • 对于特定的全局变量,[clang::no_destroy]属性跳过析构函数调用。
  • 将-fno++-静态析构函数传递给编译器,以跳过所有静态变量的析构函数.此标志还跳过thread_local变量的析构函数。如果存在具有重要析构函数的thread_local变量,则可以用[clang::always_destroy]注释这些变量以覆盖编译器标志。
  • 将退出时间析构函数传递给编译器,使其对退出时析构函数的每个实例发出警告,以突出显示__cxa_atexit注册来自何处。
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64576236

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档