我正在尝试使用许多测试方法为Activity创建单元测试。但是在大约31次测试之后,应用程序被杀死了,因为堆内存不足。
1152 E SurfaceFlinger createSurface() failed, generateId = -12
1152 W WindowManager OutOfResourcesException creating surface
1152 I WindowManager Out of memory for surface! Looking for leaks...
1152 W WindowManager No leaked surfaces; killing applicatons!
1152 W ActivityManager Killing processes Free memory at adjustment 1
我用40个相同的简单测试用例进行了单元测试,以找出问题所在。但感觉GC在测试期间没有足够快的速度来清理内存。
这是我的leakTest测试用例:
package my.app;
import android.os.Debug;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
public class leakTest extends
ActivityInstrumentationTestCase2<TestActivityAndroid> {
String TAG = "leakTest";
TestActivityAndroid mActivity = null;
public leakTest() {
super(TestActivityAndroid.class);
}
protected void setUp() throws Exception {
super.setUp();
setActivityInitialTouchMode(false);
mActivity = getActivity();
}
protected void tearDown() throws Exception {
super.tearDown();
}
private void printHeapSize() {
Log.e(TAG,
"NativeHeapAllocatedSize = "
+ Debug.getNativeHeapAllocatedSize());
Log.e(TAG, "NativeHeapFreeSize = " + Debug.getNativeHeapFreeSize());
Log.e(TAG, "NativeHeapSIZE = " + Debug.getNativeHeapSize());
}
public void test_1() {
assertNotNull(mActivity);
}
public void test_2() {
assertNotNull(mActivity);
}
public void test_3() {
assertNotNull(mActivity);
}
public void test_4() {
assertNotNull(mActivity);
}
public void test_5() {
assertNotNull(mActivity);
}
public void test_6() {
assertNotNull(mActivity);
}
public void test_7() {
assertNotNull(mActivity);
}
public void test_8() {
assertNotNull(mActivity);
}
public void test_9() {
assertNotNull(mActivity);
}
public void test_10() {
assertNotNull(mActivity);
}
public void test_11() {
assertNotNull(mActivity);
}
public void test_12() {
assertNotNull(mActivity);
}
public void test_13() {
assertNotNull(mActivity);
}
public void test_14() {
assertNotNull(mActivity);
}
public void test_15() {
assertNotNull(mActivity);
}
public void test_16() {
assertNotNull(mActivity);
}
public void test_17() {
assertNotNull(mActivity);
}
public void test_18() {
assertNotNull(mActivity);
}
public void test_19() {
assertNotNull(mActivity);
}
public void test_20() {
assertNotNull(mActivity);
}
public void test_21() {
assertNotNull(mActivity);
}
public void test_22() {
assertNotNull(mActivity);
}
public void test_23() {
assertNotNull(mActivity);
}
public void test_24() {
assertNotNull(mActivity);
}
public void test_25() {
assertNotNull(mActivity);
}
public void test_26() {
assertNotNull(mActivity);
}
public void test_27() {
assertNotNull(mActivity);
}
public void test_28() {
assertNotNull(mActivity);
}
public void test_29() {
assertNotNull(mActivity);
}
public void test_30() {
assertNotNull(mActivity);
}
public void test_31() {
assertNotNull(mActivity);
}
public void test_32() {
assertNotNull(mActivity);
}
public void test_33() {
assertNotNull(mActivity);
}
public void test_34() {
assertNotNull(mActivity);
}
public void test_35() {
assertNotNull(mActivity);
}
public void test_36() {
assertNotNull(mActivity);
}
public void test_37() {
assertNotNull(mActivity);
}
public void test_38() {
assertNotNull(mActivity);
}
public void test_39() {
assertNotNull(mActivity);
}
public void test_40() {
assertNotNull(mActivity);
}
}
扩展活动的测试活动:
package my.app;
import android.app.Activity;
import android.os.Bundle;
public class TestActivityAndroid extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
以下是内存使用情况,其中本机可用空间降至30kB以下且应用程序被杀死。
Applications Memory Usage (kB): Uptime: 3804373 Realtime: 3804373
** MEMINFO in pid 7315 [my.app] **
native dalvik other total
size: 4048 3271 N/A 7319
allocated: 3942 2306 N/A 6248
free: 105 965 N/A 1070
(Pss): 844 1590 1806 4240
(shared dirty): 1404 4120 2288 7812
(priv dirty): 736 672 992 2400 Objects
Views: 0 ViewRoots: 0
AppContexts: 0 Activities: 0
Assets: 2 AssetManagers: 2
Local Binders: 11 Proxy Binders: 10
Death Recipients: 0
OpenSSL Sockets: 0
SQL
heap: 0 memoryUsed: 0
pageCacheOverflo: 0 largestMemAlloc: 0
Asset Allocations
zip:/data/app/my.app-1.apk:/resources.arsc: 1K
有人有一个更好的解决方案,2秒睡在tearDown()内吗?我不喜欢tearDown()里面的睡眠。而且因为我们的测试套件中有大约100个测试,所以2秒将是一个巨大的延迟。
我希望有人可以帮助我,如果我的问题不明确,请告诉我。
提前致谢。
答案 0 :(得分:2)
为什么在每次单元测试后都需要执行gc?
如果是因为您想要一个干净的测试环境,那么就要忍受2秒的延迟。 tearDown至少有2 gc和一些最终确定。它为您的下一次测试留下了干净的环境。如果您通读了android源代码,那么有几条注释表明在测试结束时callilng tearDown的迫切需要。
如果您的测试不需要干净的环境,请将它们组合起来。话虽如此,在幕后运行200秒的过程对于测试给你的保护来说是一个很小的代价。
我们对当前大项目的自动化测试大约需要5分钟。我从来没有注意到,因为我们已经自动化系统在初始登记时运行测试,如果失败则退回提交。
他们失败了几次,我真的很惊讶我改变的代码弄乱了应用程序的其他部分。通过我们的自动化测试,我们至少节省了几周,并且可能需要数月才能维护和调试我们的应用程序。