Android 自动化触发GC

问题

最近有个小需求,能通过自动化对app进行GC回收

对于app的处理无外乎主动调用System.gc()或者使用adb命令直接进行GC回收

解决方法

方法一

在代码里的某个方法调用System.gc(),如我申明一个receiver,然后通过接受外不广播,去调用System.gc()完成gc回收的触发,如

public class GCReceiver extends BroadcastReceiver {
    private static final String TAG = "GCReceiver";
    private static final String ACTION_GC = "com.tomes.ACTION_GC";

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        Log.i(TAG, "onReceive: " + action);
        if (ACTION_GC.equals(action)) {
            System.gc();
        }
    }
}
        <receiver
            android:name="com.tomes.GCReceiver">

            <intent-filter>
                <action android:name="com.tomes.ACTION_GC" />
            </intent-filter>
        </receiver>

需要触发的时候,只需要执行adb命令

adb shell am broadcast -a com.tomes.ACTION_GC -f 0x01000000 --es configs 0xCF0400

方法二

有没有不要额外给app编码的方法去触发gc回收呢?有的

直接上答案,adb shell进入手机的shell环境

kill -10 应用pid

触发结果如下:

2022-03-31 14:42:43.750 13997-14011/com.tomes.gctest I/.tomes.gctest: SIGUSR1 forcing GC (no HPROF) and profile save
2022-03-31 14:42:43.782 13997-14011/com.tomes.gctest I/.tomes.gctest: Explicit concurrent copying GC freed 44(32KB) AllocSpace objects, 0(0B) LOS objects, 79% free, 1577KB/7721KB, paused 92us total 31.781ms

有些小伙伴在执行kill -10 时可能会提示

sh: kill: 13997: Permission denied

这时,你需要权限,root手机可以切换到root用户,非root手机的,在app是debug模式时

则可以执行run-as命令去拿到权限

run-as 包名

kill -10 GC的原理探究

查看as如何强制触发gc的

源码如下(由于源码很清晰,所以不再做额外的解释):

//bionic/libc/kernel/uapi/asm-x86/asm/signal.h
//定义信号量
#define SIGUSR1 10
//art/runtime/signal_catcher.cc
void* SignalCatcher::Run(void* arg) {
  SignalCatcher* signal_catcher = reinterpret_cast<SignalCatcher*>(arg);
  CHECK(signal_catcher != nullptr);

  Runtime* runtime = Runtime::Current();
  CHECK(runtime->AttachCurrentThread("Signal Catcher", true, runtime->GetSystemThreadGroup(),
                                     !runtime->IsAotCompiler()));

  Thread* self = Thread::Current();
  DCHECK_NE(self->GetState(), ThreadState::kRunnable);
  {
    MutexLock mu(self, signal_catcher->lock_);
    signal_catcher->thread_ = self;
    signal_catcher->cond_.Broadcast(self);
  }

  // Set up mask with signals we want to handle.
  SignalSet signals;
  signals.Add(SIGQUIT);
  signals.Add(SIGUSR1);

  while (true) {
    int signal_number = signal_catcher->WaitForSignal(self, signals);
    if (signal_catcher->ShouldHalt()) {
      runtime->DetachCurrentThread();
      return nullptr;
    }

    switch (signal_number) {
    case SIGQUIT:
      signal_catcher->HandleSigQuit();
      break;
    //处理接收到的信号量10
    case SIGUSR1:
    //强制GC回收
      signal_catcher->HandleSigUsr1();
      break;
    default:
      LOG(ERROR) << "Unexpected signal %d" << signal_number;
      break;
    }
  }
}
//art/runtime/signal_catcher.cc
void SignalCatcher::HandleSigUsr1() {
  //这里我们能看到系统里打印出来的日志,作为佐证
  LOG(INFO) << "SIGUSR1 forcing GC (no HPROF) and profile save";
  Runtime::Current()->GetHeap()->CollectGarbage(/* clear_soft_references= */ false);
  ProfileSaver::ForceProcessProfiles();
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值