所以我做了一个使用大量线程的应用程序/ Runnable(我们正在谈论300多个)来下载大量内容。这在模拟器和一些设备(如三星Galaxy S3)上工作正常但由于某些原因在HTC One和其他设备上我的线程或服务被停止而没有任何通知,警告,错误。应用程序继续运行,但启动所有线程的任何服务/线程都被终止。
我尝试过的事情:
来自HTC One的Logcat与START_STICKY和startForeground(刚刚保存的数据称为POI,开始下载26号然后停止):
05-23 14:52:54.732: D/libc(17514): [NET] getaddrinfo+,hn 13(0x6170692e706172),sn(),family 0,flags 4
05-23 14:52:54.732: D/libc(17514): [NET] getaddrinfo-,err=8
05-23 14:52:55.363: D/historie(17514): save POI id: jtyvZD9bX9
05-23 14:52:55.383: D/historie(17514): Starting poi number: 26
05-23 14:52:57.595: D/WifiStateMachine(705): fetchRssiAndLinkSpeedNative RSSI = -65 abnormalRssiCnt = 0 newLinkSpeed = 72
05-23 14:52:57.595: D/WifiStateMachine(705): fetchRssiAndLinkSpeedNative mLinkspeedCount = 1, mLinkspeedSum: 72
05-23 14:52:59.998: D/PMS(705): acquireWL(4237bc08): PARTIAL_WAKE_LOCK AlarmManager 0x1 705 1000
05-23 14:53:00.028: D/PMS(705): releaseWL(4237bc08): PARTIAL_WAKE_LOCK AlarmManager 0x1
05-23 14:53:00.048: I/ClockThread(996): now=1400849580059 next=59941
05-23 14:53:00.068: W/MastheadClock(1546): mDigitAnimMin.start
05-23 14:53:00.608: D/WifiStateMachine(705): fetchRssiAndLinkSpeedNative RSSI = -65 abnormalRssiCnt = 0 newLinkSpeed = 72
05-23 14:53:00.608: D/WifiStateMachine(705): fetchRssiAndLinkSpeedNative mLinkspeedCount = 2, mLinkspeedSum: 144
05-23 14:53:03.642: D/WifiStateMachine(705): fetchRssiAndLinkSpeedNative RSSI = -65 abnormalRssiCnt = 0 newLinkSpeed = 72
05-23 14:53:03.642: D/WifiStateMachine(705): fetchRssiAndLinkSpeedNative mLinkspeedCount = 3, mLinkspeedSum: 216
05-23 14:53:06.675: D/WifiStateMachine(705): fetchRssiAndLinkSpeedNative RSSI = -64 abnormalRssiCnt = 0 newLinkSpeed = 72
05-23 14:53:06.675: D/WifiStateMachine(705): fetchRssiAndLinkSpeedNative mLinkspeedCount = 4, mLinkspeedSum: 288
05-23 14:53:09.698: D/WifiStateMachine(705): fetchRssiAndLinkSpeedNative RSSI = -64 abnormalRssiCnt = 0 newLinkSpeed = 72
05-23 14:53:09.698: D/WifiStateMachine(705): fetchRssiAndLinkSpeedNative mLinkspeedCount = 5, mLinkspeedSum: 360
05-23 14:53:09.698: D/WifiStateMachine(705): fetchRssiAndLinkSpeedNative: Update RSSI:-64 and linkspeed:72 in database
05-23 14:53:09.698: D/WifiApDatabaseHandler(705): updateConnectedAP...
修改1 :
因此,手动调用GC使我能够下载更多数据,然后再次停止,所以每次下载新数据时都可以通过调用GC来解决它。这是我目前的实现,但为什么完成的线程会占用内存?有没有更好的方法呢?
答案 0 :(得分:1)
可能是您正在达到Android系统可以处理的线程数量的限制。
你提到你使用ExecutorService
。默认情况下,只有 5 主题可以同时运行,限制 128 主题可以排队。
查看AsyncTask的源代码 CORE_POOL_SIZE 是可以同时运行的任务数, MAXIMUM_POOL_SIZE 是可以排队的线程数。
答案 1 :(得分:1)
运行GC永远不是解决方案!它只是表明代码实现不好。
您没有提供代码,但是从您描述的方案中,您会在系统中溢出对象和数据,这就是您需要不时地调用GC的原因。
确保您重复使用对象,例如。 - 即使您使用的是threadPool - 您是否重用了runnables或者只是为每个线程创建一个新的runnable?
如果您使用Task作为示例,请确保取消并清除其TimerTask。清除将清除所有已结束的任务,
由于只有2个线程同步存在,因此线程并发不会产生该问题。
答案 2 :(得分:0)
我最终使用的解决方案在没有崩溃或停止的情况下运行:
System.gc();
startNewThreadAction();
这有效,但主要的问题是我不得不用这么多线程来讨论。如果您可以在许多线程和大量数据之间进行选择,那就可以获得大量数据。