【问题标题】:libc: pthread_create failed: couldn't allocate 1040384-byte stack: Out of memorylibc:pthread_create 失败:无法分配 1040384 字节堆栈:内存不足
【发布时间】:2018-10-11 02:52:45
【问题描述】:

我有一个 EventBus() 运行并循环,直到我的应用程序启动时它转到我的另一个 Fragment。当我将应用程序闲置至少 30++ 分钟时,我得到了这个堆栈跟踪:

10-11 10:23:46.315 3790-4797/com.jti.mikee.jti_pos W/libc: pthread_create failed: couldn't allocate 1040384-byte stack: Out of memory
10-11 10:23:46.315 3790-4797/com.jti.mikee.jti_pos E/dalvikvm: pthread_create (stack size 16384 bytes) failed: Try again

我也在onCreateView()上使用ScheduleExecutorService()

scheduledExecutorService = Executors.newScheduledThreadPool(4);

这是我EventBus()的声明

 public static final Runnable mRunnable = new Runnable() {
    @Override
    public void run() {
        EventBus.getDefault().post(new EB_TapCard());
    }
};

在我的onResume() 这是代码

 @Override
public void onResume() {
    Log.e("current_module",current_module);

    super.onResume();
    try {
        EventBus.getDefault().register(this);
        rfscanner = scheduledExecutorService.scheduleAtFixedRate(mRunnable, 0, 2, TimeUnit.SECONDS);
    } catch (Throwable e) {
        e.printStackTrace();
    }
}

最后,这是我的onPause() 方法

 @Override
public void onPause() {
    try {
        getContext().unregisterReceiver(broadcastReceiver);
    } catch (Throwable e) {
        e.printStackTrace();
    }
    rfscanner.cancel(true);
    EventBus.getDefault().unregister(this);
    super.onPause();
}

我想知道当我闲置设备时,可运行对象仍在运行。如何暂停/恢复它?非常感谢。

编辑

到目前为止,我已经尝试添加一个函数Callback()。它运行良好,但在我点击卡片后,读卡器没有读取第二张卡片。我怎样才能让它循环而不使内存满??

class CallBackThread extends Thread {

    @Override
    public void run() {

        try {
            RFCardInterface.waitForCardPresent(RFCardInterface.CONTACTLESS_CARD_MODE_AUTO, 1, -1);
            if (RFCardInterface.isCallBackCalled &&
                    RFCardInterface.notifyEvent.eventID == RFCardInterface.CONTACTLESS_CARD_EVENT_FOUND_CARD) {

                IDCatcher = StringUtility.ByteArrayToString(RFCardInterface.notifyEvent.eventData,
                        RFCardInterface.notifyEvent.eventData.length);

                IDCatcher = IDCatcher.substring(9, 21).replace(" ", "");
                Log.e("IDCatcher", IDCatcher);


                EventBus.getDefault().post(new EBTest2());
            }

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

【问题讨论】:

  • 你想完成什么?阅读您的代码,我无法弄清楚......一旦页面处于前台,您想每 2 秒通过 EventBus 不断广播事件吗?还是……?
  • 每 2 秒通过 EventBus 发布一个事件,我怀疑它会创建 OOM 异常。鉴于您提供的少量信息,我最好的猜测是执行程序或线程池是不断创建的,并且从不 gcc'd。
  • “我们有一个 RFID 读卡器,它需要读取特定的卡才能进行交易”-> 为什么需要 2 秒 ping 才能做到这一点?为什么不能在需要时按需阅读?
  • 尝试以下方法:忘记池和执行程序,只需 onCreate() 实例化页面的处理程序 new Handler() 并延迟 2 秒后将其发布到它的可运行你有。保留对可运行文件的引用。 OnPause() 从(引用的)处理程序中删除(引用的)可运行文件。添加它 onResume()。这清楚还是您想查看代码?试试看,我想它会解决你的OOM。
  • 你去!这是我最好的猜测,考虑到我所拥有的一些细节,修复你的崩溃......为了确保它确实如此,你要么尝试我的建议,看看崩溃不再发生,要么调试并找出确切的原因错误发生在您的代码中,因此要充分理解。我的直觉是,使用 executors 而所有这些都是罪魁祸首,Android 系统为您提供了更好的机制来完成您的任务

标签: android executorservice scheduledexecutorservice event-bus


【解决方案1】:

尝试以下方法:

private Handler mHandler;                           // the handler to this activity
private Runnable mCallback;        // the callback to 2s loop

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // ...
    mHandler = new Handler();
    mCallback = new Runnable() {
        @Override
        public void run() {
            EventBus.getDefault().post(new EB_TapCard());
            // schedule next run here
            scheduleNextRun();            
        }
    };
}

@Override
public void onResume() {
    scheduleNextRun();
} 

@Override
public void onPause() {
    cleanUpRun();
} 

@Override
public void onDestroy() {
    // needed in case the system will force-kill your process
    cleanUpRun();
} 

private void cleanUpRun() {
    if (mHandler != null) {
        mHandler.removeCallbacks(mCallback);
    }
}

private void scheduleNextRun() {
    // clean up beforehand
    cleanUpRun();
    if (mHandler != null) {
        mHandler.postDelayed(mCallback, 2000L);
    }
}

想法是每次进入页面时,都会对runnable进行post-delay,外出时将其移除;一旦你运行它,它就会执行回调,你安排下一次运行,等等。

【讨论】:

  • 您好@Alessio,到目前为止我已经尝试过这个答案。读卡器运行良好。但即使设备空闲,日志和进程仍在运行。
  • 你好。让设备屏幕打开但待机 1 小时后,我仍然收到错误消息。这是 sn-p pastebin.com/sHnP0Ent
  • @MikeGorospe 很遗憾听到这个消息......这很奇怪......堆栈跟踪没有指向任何地方,正如我所看到的......你是否删除/注释掉了所有不需要的代码,特别是关于创建执行器和线程池的那个?
  • 如果您没有在该设备上安装您的应用程序,也不会发生这种情况,对吧?它是什么设备,正在运行哪个 Android 版本?最后但并非最不重要的一点是,“设备屏幕处于打开状态但处于待机状态”究竟是什么意思?我的意思是,你打开设备,按下“主页”按钮,让你的应用程序进入后台(或者你是否将其保持在前台?),然后在某一时刻屏幕变黑?
  • 另外,使用 Studio,您可以分析您的记忆,并尝试查看在 OOM 之前不断增加的内容
猜你喜欢
  • 1970-01-01
  • 2020-06-25
  • 2018-12-05
  • 2019-05-05
  • 2018-09-29
  • 1970-01-01
  • 2020-03-20
  • 2016-12-19
  • 1970-01-01
相关资源
最近更新 更多