社交App主页Activity内存占用过高求助(无Fragment仍占140MB)
解决HomePage Activity内存占用过高的问题
让我们一步步拆解你的问题:即使禁用了帖子Fragment,HomePage仍占用120-140MB内存,结合你给出的代码,我们从几个关键方向排查和修复:
一、优化Glide图片加载的内存占用
你用Glide加载用户头像时,虽然设置了override(100,100)压缩尺寸,但还有可以优化的点:
- 给Glide加上磁盘缓存策略,只缓存压缩后的资源,避免原图占用内存:
Glide.with(HomePage.this) .load(dataSnapshot.child("pic").getValue(String.class)) .override(100,100) .thumbnail(0.5f) .diskCacheStrategy(DiskCacheStrategy.RESOURCE) .into(profilePic); - 记得在Activity销毁时清理Glide的图片请求,防止资源泄漏:在
onDestroy()方法里加一行Glide.with(this).clear(profilePic);。
二、排查侧边抽屉的内存泄漏
你用DrawerBuilder创建的侧边抽屉,很可能持有Activity的强引用导致内存无法释放:
- 在
onDestroy()方法里主动关闭抽屉并释放引用:@Override protected void onDestroy() { super.onDestroy(); if (result != null) { result.closeDrawer(); result = null; } } - 另外,检查
DrawerBuilder的withActivity(HomePage.this),如果允许的话,换成getApplicationContext()来减少Activity引用的持有时间。
三、优化Firebase相关操作的内存占用
- Token更新优化:你现在每次启动Activity都会更新FCM Token,这没必要,只在Token变化时更新就行:
String currentToken = FirebaseInstanceId.getInstance().getToken(); String savedToken = getSharedPreferences("AyePref", MODE_PRIVATE).getString("fcm_token", null); if (currentToken != null && !currentToken.equals(savedToken)) { FirebaseDatabase.getInstance().getReference().child("userdata").child(username).child("token").setValue(currentToken); getSharedPreferences("AyePref", MODE_PRIVATE).edit().putString("fcm_token", currentToken).apply(); } - 监听器清理:虽然用的是
addListenerForSingleValueEvent(单次监听),但如果Activity在回调前销毁,还是可能有短暂泄漏。建议把监听器和对应的DatabaseReference存为成员变量,在onDestroy()里移除:// 先在类里声明成员变量 private DatabaseReference usernameRef; private ValueEventListener usernameListener; // 在getUsername()里赋值 usernameRef = FirebaseDatabase.getInstance().getReference().child("users").child(FirebaseAuth.getInstance().getCurrentUser().getUid()).child("username"); usernameListener = new ValueEventListener() { // ...你的回调逻辑 }; usernameRef.addListenerForSingleValueEvent(usernameListener); // 在onDestroy()里移除 @Override protected void onDestroy() { super.onDestroy(); if (usernameRef != null && usernameListener != null) { usernameRef.removeEventListener(usernameListener); } }
四、清理ViewPager的资源
虽然你注释了fragContainer.setAdapter(adapter);,但之前设置的fragContainer.setOffscreenPageLimit(4);还是会让ViewPager保持预加载的配置。在onDestroy()里加上fragContainer.setAdapter(null);,彻底释放ViewPager的资源。
五、其他细节优化
- ProgressDialog:在
onDestroy()里调用progressDialog.dismiss();并把progressDialog = null;,防止窗口资源泄漏。 - 布局图片:检查
splash、header布局里的图片是不是太大(比如分辨率远超屏幕尺寸),把图片压缩到合适大小,这能减少初始内存占用。 - UserData类:看看
UserData(this)是不是持有Activity的强引用,如果是单例,一定要用getApplicationContext(),不然会导致Activity无法被回收。
六、用工具定位问题
推荐用Android Studio的Memory Profiler:
- 记录内存快照,看看哪些对象占了大量内存,特别是HomePage实例有没有被其他对象(比如监听器、单例)持有。
- 也可以用LeakCanary库,它能自动检测并提示内存泄漏的具体原因,帮你快速定位问题。
内容的提问来源于stack exchange,提问作者Bucky
相关产品推荐
相关产品推荐

