Android UpdateOmadjLocked()中的throwIndexOutOfBoundsException
在我的测试中,我在ActivityManagerService的UpdateOmadjLocked()中看到以下异常:Android UpdateOmadjLocked()中的throwIndexOutOfBoundsException,android,frameworks,Android,Frameworks,在我的测试中,我在ActivityManagerService的UpdateOmadjLocked()中看到以下异常: // java.lang.IndexOutOfBoundsException: Invalid index 27, size is 27 // at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251) // at java.util.ArrayList.get(ArrayList.ja
// java.lang.IndexOutOfBoundsException: Invalid index 27, size is 27
// at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
// at java.util.ArrayList.get(ArrayList.java:304)
// at com.android.server.am.ActivityManagerService.updateOomAdjLocked(ActivityManagerService.java:13880)
// at com.android.server.am.ActivityManagerService.updateLruProcessLocked(ActivityManagerService.java:1904)
// at com.android.server.am.ActivityStack.realStartActivityLocked(ActivityStack.java:647)
// at com.android.server.am.ActivityStack.startSpecificActivityLocked(ActivityStack.java:803)
问题代码如下(Android 4.2.2 r1.2的第13850行):
final ArrayList mlru进程
=新的ArrayList();
{...}
最终作废更新omadjlocked(){
{...}
final int N=mlruprocesss.size();
对于(i=0;i可以验证mLruProcess.size()
的大小在循环中仍然等于N
final boolean updateOomAdjLocked() {
{...}
final int N = mLruProcess.size();
for(int i = 0; i < N; i++) {
if(N != mLruProcess.size()) {
//Do something accordingly, in this case return false
return false;
}
ProcessRecord app = mLruProcess.get(i);
{...}
}
{...}
return true;
}
final boolean updateOmadjLocked(){
{...}
final int N=mLruProcess.size();
对于(int i=0;i
在调用此函数的地方添加一些逻辑,如果它返回false,请尝试让它再次调用该函数。否则,您可以将mLruProcess
放入Synchronized
块中,这意味着只能在一个并发线程中访问它。Synchronized
关键字是blocking,这意味着任何试图访问另一个线程中的访问mLruProcess
将被阻止,直到当前线程使用mLruProcess完成
如果您不喜欢或无法使用阻止代码,请尝试使用AtomicBoolean
,如下所示:
每当您更改mLruProcess
中存储的对象时,请设置AtomicBoolean
,然后检查AtomicBoolean
中存储的对象是否需要访问mLruProcess
中存储的对象。我认为他无法修改这些内部结构,而是在寻找解决方案以避免这(似乎是无意的)并发问题。谢谢,David和Mattias。是的,有几种方法可以避免此异常,并且每种方法都必须进行评估,以确保不破坏OOM adj逻辑。大多数情况下,我想知道这是否应该是可重新输入的代码,可以意识到并发问题。以谷歌的方式,似乎不是这样。事实上,我遇到此异常似乎是必须的。因为此方法声明为final
,所以无法修改。至少OP可以查看AtomicBoolean
以尝试解决他/她的问题。
final boolean updateOomAdjLocked() {
{...}
final int N = mLruProcess.size();
for(int i = 0; i < N; i++) {
if(N != mLruProcess.size()) {
//Do something accordingly, in this case return false
return false;
}
ProcessRecord app = mLruProcess.get(i);
{...}
}
{...}
return true;
}