You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

社交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相关操作的内存占用

  1. 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();
    }
    
  2. 监听器清理:虽然用的是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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:49:06