我在Android上遇到内存泄漏问题 我有一个简单的应用程序,相对图片作为背景,它工作正常,直到我改变方向。
以下是显示内存泄漏(随时间分配的内存)的图表。每个尖峰对应一个方向变化,每个尖峰是+ 20M的分配内存
在大约30秒时,应用程序崩溃了一个明显的" OutOfMemory"错误:
抛出OutOfMemoryError"无法分配带有804912个空闲字节的17469452字节分配和786KB直到OOM"`
布局只是一个简单的RelativeLayout
,背景是jpeg图像
大小〜430k
我确实实施了onDestroy()
反内存泄漏解决方案(建议here):
@Override
protected void onDestroy()
{
unbindDrawables(view);
view = null;
System.gc();
super.onDestroy();
}
private void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
但实际上并没有改变任何事情。
我能解决这个问题吗? 我确实需要图像那么大,因为运行应用程序的设备有一个大屏幕。
- 编辑 -
按要求添加onCreate()
代码,
请注意,即使没有调用initMainView()
,即使有一个空onCreate()
(仅限超级),问题仍然存在,即使内存泄漏较差(仅0.8M),但仍然存在。<登记/>
我在Pixel C上运行Android 6.0.1,如果这可能会有所帮助。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
System.gc();
w = getWindow();
w.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
dpm = (DevicePolicyManager) this.getSystemService(Context.DEVICE_POLICY_SERVICE);
deviceAdmin = new ComponentName(this, AdmRcvr.class);
if(!dpm.isDeviceOwnerApp(getPackageName())) {
setContentView(R.layout.deviceownertutorial);
final TextView tvTutorial = (TextView) w.findViewById(R.id.tutorialtv);
tvTutorial.setText(Html.fromHtml(getString(R.string.deviceownertutorial)));
final TextView tvDeviceOwnerError = (TextView) w.findViewById(R.id.tverrordeviceadmin);
Button checkDeviceAdmin = (Button) w.findViewById(R.id.cdevadmin);
checkDeviceAdmin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (dpm.isDeviceOwnerApp(getPackageName())) {
runOnUiThread(new Runnable() {
@Override
public void run() {
setContentView(R.layout.startview);
initMainView();
}
});
} else {
runOnUiThread(new Runnable() {
@Override
public void run() {
tvDeviceOwnerError.setText("App is not the device admin");
tvDeviceOwnerError.setVisibility(View.VISIBLE);
}
});
}
}
});
}
else
{
setContentView(R.layout.startview);
initMainView();
}
}
public void initMainView(){
// We're device owners!
View mDecorView = w.getDecorView();
mDecorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
mDecorView = null;
view = findViewById(R.id.sv_relativelayout);
initReader();
initBitmapCache();
enableTimer();
currentStep = 1;
}
---编辑2 ---
在下面的图像中,你可以看到两种情况下的内存分配:我的所有app垃圾(如430kB图像)[a]和没有(一个干净的onCreate()
)[b]。
请注意,如上所述,在这两种情况下仍然存在内存泄漏,即使很难,也不会那么大(但有!)。
该应用程序是针对SDK v.23和buildToolsVersion 23.0.2编译的。 依赖关系如下:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.2.1'
compile 'com.android.support:design:23.2.1'
}
app / libs如下:
libs
└── acssmc-1.1.2.jar
---编辑3 ---
在使用新创建的应用程序进行测试时,内存将按预期进行管理,您可以在我的GitHub repo上看到一个示例