Пример #1
0
    def _dumpsys_process_meminfo(self, process):
        '''
        dump 进程详细内存 耗时 1s以内
        :param process:
        :return:
        '''
        time_old = time.time()
        out = self.device.adb.run_shell_cmd('dumpsys meminfo %s' % process)
        # self.num = self.num + 1
        # if self.num % 10 == 0:
        #避免:在windows 无法创建文件名,不能有冒号:
        process_rename = process.replace(":", "_")
        meminfo_file = os.path.join(RuntimeData.package_save_path,
                                    'dumpsys_meminfo_%s.txt' % process_rename)
        with open(meminfo_file, "a+") as writer:
            writer.write(TimeUtils.getCurrentTime() +
                         " dumpsys meminfo package info:\n")
            if out:
                writer.write(out + "\n\n")
            # self.num = 0

        passedtime = time.time() - time_old  #测试meminfo这个命令的耗时,执行的时长在400多ms
        logger.debug("dumpsys meminfo package time consume:" + str(passedtime))
        out.replace('\r', '')
        return MemInfoPackage(dump=out)
Пример #2
0
    def _collect_thread_num_thread(self, start_time):
        end_time = time.time() + self._timeout
        thread_list_titile = ("datatime", "packagename", "pid", "thread_num")
        thread_num_file = os.path.join(RuntimeData.package_save_path,
                                       'thread_num.csv')
        try:
            with open(thread_num_file, 'a+') as df:
                csv.writer(df,
                           lineterminator='\n').writerow(thread_list_titile)
                if self.thread_queue:
                    thread_file_dic = {'thread_file': thread_num_file}
                    self.thread_queue.put(thread_file_dic)
        except RuntimeError as e:
            logger.error(e)

        while not self._stop_event.is_set() and time.time() < end_time:
            try:
                before = time.time()
                logger.debug(
                    "-----------into _collect_thread_num_thread loop, thread is : "
                    + str(threading.current_thread().name))

                # 获取pakagename的thread num信息
                thread_pck_info = self.get_process_thread_num(self.packagename)
                logger.debug(thread_pck_info)
                current_time = TimeUtils.getCurrentTime()
                if not thread_pck_info:
                    continue
                else:
                    logger.debug("current time: " + current_time +
                                 ", processname: " + thread_pck_info[1] +
                                 ", pid: " + str(thread_pck_info[2]) +
                                 " thread num: " + str(thread_pck_info[3]))
                if self.thread_queue:
                    self.thread_queue.put(thread_pck_info)
                if not self.thread_queue:  #为了本地单个文件运行
                    try:
                        with open(thread_num_file, 'a+') as thread_writer:
                            writer_p = csv.writer(thread_writer,
                                                  lineterminator='\n')
                            thread_pck_info[0] = current_time
                            writer_p.writerow(thread_pck_info)
                    except RuntimeError as e:
                        logger.error(e)

                after = time.time()
                time_consume = after - before
                delta_inter = self._interval - time_consume
                logger.debug("time_consume  for thread num infos: " +
                             str(time_consume))
                if delta_inter > 0:
                    time.sleep(delta_inter)
            except:
                logger.error(
                    "an exception hanpend in thread num thread, reason unkown!"
                )
                s = traceback.format_exc()
                logger.debug(s)
                if self.thread_queue:
                    self.thread_queue.task_done()
Пример #3
0
 def get_max_freq(self):
     out = self.device.adb.run_shell_cmd(
         "cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq")
     out.replace('\r', '')
     max_freq_file = os.path.join(RuntimeData.package_save_path,
                                  'scaling_max_freq.txt')
     with open(max_freq_file, "a+", encoding="utf-8") as writer:
         writer.write(TimeUtils.getCurrentTime() + " scaling_max_freq:\n")
         writer.write(out + "\n\n")
Пример #4
0
 def _monkey_thread_func(self,save_dir):
     '''获取monkey线程,保存monkey日志,monkey Crash日志暂不处理,后续有需要再处理
     '''
     self.append_log_line_num = 0
     self.file_log_line_num = 0
     self.log_file_create_time = None
     log_is_none = 0
     logs = []
     logger.debug("monkey_thread_func")
     if RuntimeData.start_time is None:
         RuntimeData.start_time = TimeUtils.getCurrentTime()
     while self.running:
         try:
             log = self._log_pipe.stdout.readline().strip()
             if not isinstance(log, str):
                 # 先编码为unicode
                 try:
                     log = str(log, "utf8")
                 except Exception as e:
                     log = repr(log)
                     logger.error('str error:' + log)
                     logger.error(e)
             if log:
                 logs.append(log)
                 self.append_log_line_num = self.append_log_line_num + 1
                 self.file_log_line_num = self.file_log_line_num + 1
                 # if self.append_log_line_num > 1000:
                 if self.append_log_line_num > 100:
                     if not self.log_file_create_time:
                         self.log_file_create_time = TimeUtils.getCurrentTimeUnderline()
                     log_file = os.path.join(save_dir,
                                             'monkey_%s.log' % self.log_file_create_time)
                     self.append_log_line_num = 0
                     # 降低音量,避免音量过大,导致语音指令失败
                     self.device.adb.run_shell_cmd("input keyevent 25")
                     self.save(log_file, logs)
                     logs = []
                 # 新建文件
                 if self.file_log_line_num > 600000:
                     # if self.file_log_line_num > 200:
                     self.file_log_line_num = 0
                     self.log_file_create_time = TimeUtils.getCurrentTimeUnderline()
                     log_file = os.path.join(save_dir, 'monkey_%s.log' % self.log_file_create_time)
                     self.save(log_file, logs)
                     logs = []
             else:
                 log_is_none = log_is_none + 1
                 if log_is_none % 1000 == 0:
                     logger.info("log is none")
                     if not self.device.adb.is_process_running("com.android.commands.monkey") and self.running:
                         self.device.adb.kill_process("com.android.commands.monkey")
                         self._log_pipe = self.device.adb.run_shell_cmd(self.monkey_cmd, sync=False)
         except:
             logger.error("an exception hanpend in monkey thread, reason unkown!")
             s = traceback.format_exc()
             logger.debug(s)
Пример #5
0
    def _parse_package(self):
        '''
        解析top命令中的包的cpu信息
        :return:
        '''
        if self.packages == None or self.packages == "":
            logger.error("no process name input, please input")

        for package in self.packages:
            package_dic = {"package": package, "pid": "", "pid_cpu": ""}
            sp_lines = self.source.split('\n')
            for line in sp_lines:
                # logger.debug(line)
                if package in line:  #解析进程cpu信息
                    tmp = line.split()
                    self.pid = tmp[0]
                    target_pck = tmp[-1]  #从中解析出的最后一个值是包名
                    self.datetime = TimeUtils.getCurrentTime()
                    logger.debug("cpuinfos, _parse top target_pck is : " +
                                 str(target_pck) + " , self.pacakgename : " +
                                 package)
                    if package == target_pck:  #只统计包名完全相同的进程
                        if int(self.pid) > 0:
                            logger.debug(
                                "cpuinfos, into _parse_pck packege is target package, pid is :"
                                + str(self.pid))
                            # logger.debug("into _parse_pck packege is target package, pid is :" + str(self.pid))
                            cpu_index = self.get_cpucol_index()
                            uid_index = self.get_uidcol_index()
                            if (len(tmp) > cpu_index):
                                self.pck_cpu_rate = tmp[cpu_index]
                                # CPU% 9% 有的格式会有%
                                self.pck_cpu_rate = self.pck_cpu_rate.replace(
                                    "%", "")
                            if (len(tmp) > uid_index):
                                self.uid = tmp[uid_index]
                            package_dic = {
                                "package": package,
                                "pid": self.pid,
                                "pid_cpu": str(self.pck_cpu_rate),
                                "uid": self.uid
                            }
                            # self.package_list.append(package_dic)
                            # 将top中解析出来的信息保存在一个列表中,作为一条记录添加在package_list中
                            logger.debug("package: " + package +
                                         ", cpu_rate: " +
                                         str(self.pck_cpu_rate))
                            self.total_pid_cpu = self.total_pid_cpu + float(
                                self.pck_cpu_rate)
                        break
            self.package_list.append(package_dic)
            logger.debug(package_dic)
Пример #6
0
    def _activity_monitor_thread(self):
        activity_title = ("datetime", "current_activity")
        self.activity_file = os.path.join(RuntimeData.package_save_path,
                                          'current_activity.csv')
        try:
            with open(self.activity_file, 'a+') as af:
                csv.writer(af, lineterminator='\n').writerow(activity_title)
        except Exception as e:
            logger.error("file not found: " + str(self.activity_file))

        while not self.stop_event.is_set():
            try:
                before = time.time()
                self.current_activity = self.device.adb.get_current_activity()
                collection_time = time.time()
                activity_list = [collection_time, self.current_activity]
                if self.activity_queue:
                    logger.debug("activity monitor thread activity_list: " +
                                 str(activity_list))
                    self.activity_queue.put(activity_list)
                if self.current_activity:
                    logger.debug("current activity: " + self.current_activity)
                    if self.main_activity and self.activity_list:
                        if self.current_activity not in self.activity_list:
                            start_activity = self.packagename + "/" + self.main_activity[
                                random.randint(0,
                                               len(self.main_activity) - 1)]
                            logger.debug("start_activity:" + start_activity)
                            self.device.adb.start_activity(start_activity)
                    activity_tuple = (TimeUtils.getCurrentTime(),
                                      self.current_activity)
                    # 写文件
                    try:
                        with open(self.activity_file, 'a+') as writer:
                            writer_p = csv.writer(writer, lineterminator='\n')
                            writer_p.writerow(activity_tuple)
                    except RuntimeError as e:
                        logger.error(e)
                time_consume = time.time() - before
                delta_inter = self.interval - time_consume
                logger.debug("get app activity time consumed: " +
                             str(time_consume))
                if delta_inter > 0:
                    time.sleep(delta_inter)
            except Exception as e:
                s = traceback.format_exc()
                logger.debug(s)  # 将堆栈信息打印到log中
                if self.activity_queue:
                    self.activity_queue.task_done()
Пример #7
0
 def _top_cpuinfo(self):
     self._top_pipe = self.device.adb.run_shell_cmd(self.top_cmd,
                                                    sync=False)
     out = self._top_pipe.stdout.read()
     error = self._top_pipe.stderr.read()
     if error:
         logger.error("into cpuinfos error : " + str(error))
         return
     out = str(out, "utf-8")
     out.replace('\r', '')
     top_file = os.path.join(RuntimeData.package_save_path, 'top.txt')
     with open(top_file, "a+", encoding="utf-8") as writer:
         writer.write(TimeUtils.getCurrentTime() + " top info:\n")
         writer.write(out + "\n\n")
     #避免文件过大,超过100M清理
     if FileUtils.get_FileSize(top_file) > 100:
         os.remove(top_file)
     return PckCpuinfo(self.packages, out, self.sdkversion)
Пример #8
0
    def _dumpsys_meminfo(self):
        '''
        总内存 各进程内存都从dumpsys meminfo中获取
        这个方法挺耗时 约6 7秒才能完成
        :return:
        '''
        time_old = time.time()
        out = self.device.adb.run_shell_cmd('dumpsys meminfo')
        meminfo_file = os.path.join(RuntimeData.package_save_path, 'dumpsys_meminfo.txt')
        with open(meminfo_file, "a+",encoding="utf-8") as writer:
            writer.write(TimeUtils.getCurrentTime()+" dumpsys meminfo info:\n")
            writer.write(out+"\n\n")
            # self.num = 0

        passedtime = time.time() - time_old#测试meminfo这个命令的耗时,执行的时长在400多ms
        logger.debug("dumpsys meminfo time consume:" + str(passedtime))
        out.replace('\r', '')
        return MemInfoDevice(dump=out,packages=self.packages)
Пример #9
0
class ThreadNumMonitor(object):
    def __init__(self,
                 device_id,
                 packagename,
                 interval=1.0,
                 timeout=24 * 60 * 60,
                 thread_queue=None):
        self.device = AndroidDevice(device_id)
        if not packagename:
            packagename = self.device.adb.get_foreground_process()
        self.thread_package_collector = ThreadNumPackageCollector(
            self.device, packagename, interval, timeout, thread_queue)

    def start(self, start_time):
        self.start_time = start_time
        self.thread_package_collector.start(start_time)

    def stop(self):
        self.thread_package_collector.stop()

    def save(self):
        pass


if __name__ == "__main__":
    monitor = ThreadNumMonitor("", "com.yunos.tv.alitvasr", 3)
    monitor.start(TimeUtils.getCurrentTime())
    time.sleep(20)
    monitor.stop()
#     monitor.save()
Пример #10
0
    def _collect_cpu_thread(self, start_time):
        end_time = time.time() + self._timeout
        cpu_title = ["datetime", "device_cpu_rate%", "user%", "system%"]
        cpu_file = os.path.join(RuntimeData.package_save_path, 'cpuinfo.csv')
        for i in range(0, len(self.packages)):
            cpu_title.append("package", "pid", "pid_cpu%")
        cpu_title.append("total_pid_cpu%")
        try:
            with open(cpu_file, 'a+') as df:
                csv.writer(df, lineterminator='\n').writerow(cpu_title)
                if self.cpu_queue:
                    cpu_file_dic = {'cpu_file': cpu_file}
                    self.cpu_queue.put(cpu_file_dic)
        except RuntimeError as e:
            logger.error(e)
        while not self.stop_device_event.is_set() and time.time() < end_time:
            try:
                before = time.time()
                logger.debug("into _collect_cpu_thread loop thread is : " +
                             str(threading.current_thread().name))
                cpu_info = self._get_cpu_usage()
                logger.debug(" get cpu info: " + str(cpu_info))

                cpu_pck_info = self._get_pck_cpu_usage()
                cpu_pck_info = self._trim_pakcage_info(cpu_pck_info, cpu_info)
                collection_time = time.time()
                logger.debug(" collection time in cpu is : " +
                             TimeUtils.getCurrentTime())
                if cpu_pck_info.pid == -1:
                    logger.debug("cpu_pck pid is -1")
                    continue
                gather_list = [
                    collection_time, cpu_info.cpu_rate, cpu_info.user_rate,
                    cpu_info.system_rate
                ]
                if self.cpu_queue:
                    self.cpu_queue.put(gather_list)
                for i in range(0, len(self.packages)):
                    gather_list.append()

                # 添加进程 总cpu使用率
                gather_list.append()

                if not self.cpu_queue:  #为了让单个脚本运行
                    gather_list[0] = TimeUtils.formatTimeStamp(gather_list[0])
                    try:
                        with open(cpu_file, 'a+', encoding="utf-8") as f:
                            csv.writer(
                                f, lineterminator='\n').writerow(gather_list)
                            logger.debug("write to file:" + cpu_file)
                            logger.debug(gather_list)
                    except RuntimeError as e:
                        logger.error(e)

                time_consume = time.time() - before
                logger.debug(
                    " _collect_cpu_thread time consume for device cpu usage: "
                    + str(format(time_consume, '0.2f')))
                delta_inter = self._interval - time_consume
                if delta_inter > 0:
                    time.sleep(delta_inter)
            except Exception as e:
                logger.error(
                    "an exception hanpend in cpu thread , reason unkown!")
                s = traceback.format_exc()
                logger.debug(s)  #将堆栈信息打印到log中
                if self.cpu_queue:
                    self.cpu_queue.task_done()
        logger.debug("stop event is set or timeout")
Пример #11
0
    def _collect_package_cpu_thread(self, start_time):
        '''
        按照指定频率,循环搜集cpu的信息
        :return:
        '''
        end_time = time.time() + self._timeout
        cpu_title = [
            "datetime", "device_cpu_rate%", "user%", "system%", "idle%"
        ]
        cpu_file = os.path.join(RuntimeData.package_save_path, 'cpuinfo.csv')
        for i in range(0, len(self.packages)):
            cpu_title.extend(["package", "pid", "pid_cpu%"])
        if len(self.packages) > 1:
            cpu_title.append("total_pid_cpu%")
        try:
            with open(cpu_file, 'a+') as df:
                csv.writer(df, lineterminator='\n').writerow(cpu_title)
        except RuntimeError as e:
            logger.error(e)
        while not self._stop_event.is_set() and time.time() < end_time:
            try:
                course = os.system(
                    'adb shell pidof com.deskmateones')  # TODO 调起同桌100
                if course == 1:
                    print("检查到同桌100没有运行,正在尝试调起")
                    os.system(
                        'adb shell am broadcast -a com.baidu.duer.query -e q "打开同桌100"'
                    )
                else:
                    pass
                logger.debug(
                    "---------------cpuinfos, into _collect_package_cpu_thread loop thread is : "
                    + str(threading.current_thread().name))
                before = time.time()
                #为了cpu值的准确性,将采集的时间间隔放在top命令中了
                cpu_info = self._top_cpuinfo()
                after = time.time()
                time_consume = after - before
                logger.debug("  ============== time consume for cpu info : " +
                             str(time_consume))
                if cpu_info == None or cpu_info.source == '' or not cpu_info.package_list:
                    logger.debug("cpuinfos, can't get cpu info, continue")
                    continue
                self.cpu_list.extend([
                    TimeUtils.getCurrentTime(),
                    str(cpu_info.device_cpu_rate), cpu_info.user_rate,
                    cpu_info.system_rate, cpu_info.idle_rate
                ])
                for i in range(0, len(self.packages)):
                    if len(cpu_info.package_list) == len(self.packages):
                        self.cpu_list.extend([
                            cpu_info.package_list[i]["package"],
                            cpu_info.package_list[i]["pid"],
                            cpu_info.package_list[i]["pid_cpu"]
                        ])
                if len(self.packages) > 1:
                    self.cpu_list.append(cpu_info.total_pid_cpu)
                #校准时间,由于top执行需要耗时,需要将这个损耗加上去
                logger.debug("INFO: CpuMonitor save cpu_device_list: " +
                             str(self.cpu_list))
                try:
                    with open(cpu_file, 'a+', encoding="utf-8") as df:
                        csv.writer(df,
                                   lineterminator='\n').writerow(self.cpu_list)
                        del self.cpu_list[:]
                except RuntimeError as e:
                    logger.error(e)

                # self.get_max_freq()
                delta_inter = self._interval - time_consume
                if delta_inter > 0:
                    time.sleep(delta_inter)
            except Exception as e:
                logger.error(
                    "an exception hanpend in cpu thread , reason unkown!, e:")
                logger.error(e)
                s = traceback.format_exc()
                logger.debug(s)  #将堆栈信息打印到log中
                if self.cpu_queue:
                    self.cpu_queue.task_done()
        logger.debug("stop event is set or timeout")
Пример #12
0
    def _collect_memory_thread(self, start_time):
        end_time = time.time() + self._timeout
        mem_list_titile = ["datatime", "total_ram(MB)", "free_ram(MB)"]
        pid_list_titile = ["datatime"]
        pss_detail_titile = [
            "datatime", "package", "pid", "pss", "java_heap", "native_heap",
            "system"
        ]
        for i in range(0, len(self.packages)):
            mem_list_titile.extend(["package", "pid", "pid_pss(MB)"])
            pid_list_titile.extend(["package", "pid"])
        if len(self.packages) > 1:
            mem_list_titile.append("total_pss(MB)")
        mem_file = os.path.join(RuntimeData.package_save_path, 'meminfo.csv')
        pid_file = os.path.join(RuntimeData.package_save_path,
                                'pid_change.csv')
        for package in self.packages:
            pss_detail_file = os.path.join(
                RuntimeData.package_save_path,
                'pss_%s.csv' % package.split(".")[-1].replace(":", "_"))
            with open(pss_detail_file, 'a+') as df:
                csv.writer(df, lineterminator='\n').writerow(pss_detail_titile)
        try:
            with open(mem_file, 'a+') as df:
                csv.writer(df, lineterminator='\n').writerow(mem_list_titile)
                if self.mem_queue:
                    mem_file_dic = {'mem_file': mem_file}
                    self.mem_queue.put(mem_file_dic)

            with open(pid_file, 'a+') as df:
                csv.writer(df, lineterminator='\n').writerow(pid_list_titile)
        except RuntimeError as e:
            logger.error(e)
        starttime_stamp = TimeUtils.getTimeStamp(start_time,
                                                 "%Y_%m_%d_%H_%M_%S")
        old_package_pid_pss_list = []
        dumpsys_mem_times = 0
        # D系统上会报错 System server has no access to file context
        # hprof_path = "/sdcard/hprof"
        hprof_path = "/data/local/tmp"
        self.device.adb.run_shell_cmd("mkdir " + hprof_path)
        # sdcard 卡目录下dump需要打开这个开关
        self.device.adb.run_shell_cmd("setenforce 0")
        first_dump = True
        while not self._stop_event.is_set() and time.time() < end_time:
            try:
                before = time.time()
                logger.debug(
                    "-----------into _collect_mem_thread loop, thread is : " +
                    str(threading.current_thread().name))
                collection_time = time.time()
                # # 获取主进程的详细信息
                for package in self.packages:
                    mem_pck_snapshot = self._dumpsys_process_meminfo(package)
                    if 0 == mem_pck_snapshot.totalPSS:
                        logger.error("package total pss is 0:%s" % package)
                        continue
                    pss_detail_file = os.path.join(
                        RuntimeData.package_save_path, 'pss_%s.csv' %
                        package.split(".")[-1].replace(":", "_"))
                    pss_detail_list = [
                        TimeUtils.formatTimeStamp(collection_time), package,
                        mem_pck_snapshot.pid, mem_pck_snapshot.totalPSS,
                        mem_pck_snapshot.javaHeap, mem_pck_snapshot.nativeHeap,
                        mem_pck_snapshot.system
                    ]
                    with open(pss_detail_file, 'a+') as pss_writer:
                        writer_p = csv.writer(pss_writer, lineterminator='\n')
                        writer_p.writerow(pss_detail_list)
                #         写到pss_detail表格中

                # 手机每5分钟 dumpheap一次
                if (before - starttime_stamp) > 300 or first_dump:
                    #     先清理hprof文件
                    filelist = self.device.adb.list_dir(hprof_path)
                    if filelist:
                        for file in filelist:
                            for package in self.packages:
                                if package in file:
                                    self.device.adb.delete_file(hprof_path +
                                                                "/" + file)
                # if (before - starttime_stamp) % 60 < self._interval and "D" in self.device.adb.get_system_version():
                    for package in self.packages:
                        self.device.adb.dumpheap(package,
                                                 RuntimeData.package_save_path)
                    starttime_stamp = before
                    # self.device.adb.run_shell_cmd("kill -10 %s"%str(mem_pck_snapshot.pid))
                # dumpsys meminfo 耗时长,可能会导致system server cpu占用变高,降低采集频率
                dumpsys_mem_times = dumpsys_mem_times + 1
                # 10倍率frequency dumpsys meminfo一次
                if dumpsys_mem_times % 10 == 0 or first_dump:
                    mem_device_snapshot = self._dumpsys_meminfo()
                    # 如果没有采集到dumpsys meminfo的信息,正常情况totalmem不可能为0
                    if mem_device_snapshot == None or not mem_device_snapshot.package_pid_pss_list or mem_device_snapshot.totalmem == 0:
                        logger.error("mem_device_snapshot is none")
                        # 如果获取不到结果,继续延长采集间隔
                        dumpsys_mem_times = dumpsys_mem_times - 1
                        continue
                    first_dump = False
                    logger.debug("current time: " +
                                 TimeUtils.getCurrentTime() +
                                 ", processname: " + ",total pss:" +
                                 str(mem_device_snapshot.total_pss))
                    logger.debug("collection time in meminfo is : " +
                                 TimeUtils.getCurrentTime())
                    gather_list = [
                        TimeUtils.formatTimeStamp(collection_time),
                        mem_device_snapshot.totalmem,
                        mem_device_snapshot.freemem
                    ]
                    pid_list = [TimeUtils.formatTimeStamp(collection_time)]
                    pid_change = False
                    for i in range(0, len(self.packages)):
                        if len(mem_device_snapshot.package_pid_pss_list
                               ) == len(self.packages):
                            gather_list.extend([
                                mem_device_snapshot.package_pid_pss_list[i]
                                ["package"],
                                mem_device_snapshot.package_pid_pss_list[i]
                                ["pid"],
                                mem_device_snapshot.package_pid_pss_list[i]
                                ["pss"]
                            ])
                    if not old_package_pid_pss_list:
                        old_package_pid_pss_list = mem_device_snapshot.package_pid_pss_list
                        pid_change = True
                    else:
                        for i in range(0, len(self.packages)):
                            package = mem_device_snapshot.package_pid_pss_list[
                                i]["package"]
                            if mem_device_snapshot.package_pid_pss_list[i]["pid"] and \
                                    old_package_pid_pss_list[i]["pid"]!=mem_device_snapshot.package_pid_pss_list[i]["pid"]:
                                pid_change = True
                                # 确保上次pid也有
                                if old_package_pid_pss_list[i]["pid"]:
                                    if package and package in RuntimeData.config_dic[
                                            "pid_change_focus_package"]:
                                        # 确保有tombstones文件才提单
                                        self.device.adb.pull_file(
                                            "/data/vendor/tombstones",
                                            RuntimeData.package_save_path)
                    if pid_change:
                        old_package_pid_pss_list = mem_device_snapshot.package_pid_pss_list
                        for i in range(0, len(self.packages)):
                            if len(old_package_pid_pss_list) == len(
                                    self.packages):
                                pid_list.extend([
                                    old_package_pid_pss_list[i]["package"],
                                    old_package_pid_pss_list[i]["pid"]
                                ])
                        try:
                            with open(pid_file, 'a+') as pid_writer:
                                writer_p = csv.writer(pid_writer,
                                                      lineterminator='\n')
                                writer_p.writerow(pid_list)
                                logger.debug("write to file:" + pid_file)
                                logger.debug(pid_list)
                        except RuntimeError as e:
                            logger.error(e)
                    if len(self.packages) > 1:
                        gather_list.append(mem_device_snapshot.total_pss)
                    if self.mem_queue:
                        gather_list[0] = collection_time
                        self.mem_queue.put(gather_list)
                    if not self.mem_queue:  #为了本地单个文件运行
                        try:
                            with open(mem_file, 'a+') as mem_writer:
                                writer_p = csv.writer(mem_writer,
                                                      lineterminator='\n')
                                writer_p.writerow(gather_list)
                                logger.debug("write to file:" + mem_file)
                                logger.debug(gather_list)
                        except RuntimeError as e:
                            logger.error(e)

                after = time.time()
                time_consume = after - before
                delta_inter = self._interval - time_consume
                logger.info("time consume for meminfos: " + str(time_consume))
                if delta_inter > 0:
                    time.sleep(delta_inter)
            except:
                logger.error(
                    "an exception hanpend in meminfo thread, reason unkown!")
                s = traceback.format_exc()
                logger.debug(s)
                if self.mem_queue:
                    self.mem_queue.task_done()

        logger.debug("stop event is set or timeout")