当前位置: 首页 > news >正文

GTS 中testPeakPssOfAllApps fail 详解

0. 前言

GTS 在测试 case armeabi-v7a GtsMemoryHostTestCases 的时候出现下面异常,本文总结一下。

com.google.android.memory.gts.AllAppsMemoryHostTest#testPeakPssOfAllApps

1. error log

09-14 10:16:34 I/TestFailureListener: FailureListener.testFailed com.google.android.memory.gts.AllAppsMemoryHostTest#testPeakPssOfAllApps false
09-14 10:16:34 D/PrettyTestEventLogger: 
==================== com.google.android.memory.gts.AllAppsMemoryHostTest#testPeakPssOfAllApps ENDED: Thu Sep 14 10:16:34 CST 2023 ====================
09-14 10:16:34 I/ModuleListener: [1/1] d4081bc5 com.android.compatibility.common.tradefed.testtype.JarHostTest com.google.android.memory.gts.AllAppsMemoryHostTest#testPeakPssOfAllApps FAILURE: com.android.tradefed.device.DeviceUnresponsiveException[DEVICE_UNRESPONSIVE|520751|LOST_SYSTEM_UNDER_TEST]: Attempted shell am start -W -S -f 10008000 'com.google.android.apps.mapslite/com.google.maps.lite.twa.MapsLiteTwaLauncherActivity' multiple times on device d4081bc5 without communication success. Aborting.at com.android.tradefed.device.NativeDevice.performDeviceAction(NativeDevice.java:2577)at com.android.tradefed.device.NativeDevice.executeShellCommand(NativeDevice.java:902)at com.android.tradefed.device.NativeDevice.executeShellCommand(NativeDevice.java:959)at com.google.android.memory.gts.AllAppsMemoryHostTest.testPeakPssOfAllApps(AllAppsMemoryHostTest.java:109)at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.base/java.lang.reflect.Method.invoke(Method.java:568)at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:61)at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:54)at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)at com.android.tradefed.testtype.DeviceJUnit4ClassRunner.runChild(DeviceJUnit4ClassRunner.java:111)at com.android.tradefed.testtype.DeviceJUnit4ClassRunner.runChild(DeviceJUnit4ClassRunner.java:63)at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)at org.junit.runners.ParentRunner.run(ParentRunner.java:413)at com.android.tradefed.testtype.DeviceJUnit4ClassRunner.run(DeviceJUnit4ClassRunner.java:147)at com.android.tradefed.testtype.junit4.ExceptionThrowingRunnerWrapper.run(ExceptionThrowingRunnerWrapper.java:43)at org.junit.runner.JUnitCore.run(JUnitCore.java:137)at com.android.tradefed.testtype.HostTest.runJUnit4Tests(HostTest.java:736)at com.android.tradefed.testtype.HostTest.runTestClasses(HostTest.java:616)at com.android.tradefed.testtype.HostTest.run(HostTest.java:564)at com.android.compatibility.common.tradefed.testtype.JarHostTest.run(JarHostTest.java:56)at com.android.tradefed.testtype.suite.GranularRetriableTestWrapper.intraModuleRun(GranularRetriableTestWrapper.java:379)at com.android.tradefed.testtype.suite.GranularRetriableTestWrapper.run(GranularRetriableTestWrapper.java:289)at com.android.tradefed.testtype.suite.ModuleDefinition.run(ModuleDefinition.java:595)at com.android.tradefed.testtype.suite.ITestSuite.runSingleModule(ITestSuite.java:951)at com.android.tradefed.testtype.suite.ITestSuite.run(ITestSuite.java:828)at com.android.tradefed.invoker.InvocationExecution.runTest(InvocationExecution.java:1359)at com.android.tradefed.invoker.InvocationExecution.runTests(InvocationExecution.java:1138)at com.android.tradefed.invoker.TestInvocation.prepareAndRun(TestInvocation.java:626)at com.android.tradefed.invoker.TestInvocation.performInvocation(TestInvocation.java:278)at com.android.tradefed.invoker.TestInvocation.invoke(TestInvocation.java:1357)at com.android.tradefed.command.CommandScheduler$InvocationThread.run(CommandScheduler.java:686)
Caused by: com.android.ddmlib.ShellCommandUnresponsiveExceptionat com.android.ddmlib.AdbHelper.executeRemoteCommand(AdbHelper.java:731)at com.android.ddmlib.AdbHelper.executeRemoteCommand(AdbHelper.java:511)at com.android.ddmlib.internal.DeviceImpl.executeShellCommand(DeviceImpl.java:722)at com.android.tradefed.device.NativeDevice$2.run(NativeDevice.java:897)at com.android.tradefed.device.NativeDevice.performDeviceAction(NativeDevice.java:2525)... 44 more

2. source code

    public void testPeakPssOfAllApps() throws Exception {final int flags = 268468224;//------------step1final String[] activities = ActivityQueryHelper.ALL_APPS_QUERY.run(this.getDevice());Assert.assertTrue("No activities found", activities.length > 0);final Set<String> exemptedActivities = new HashSet<String>();for (final ActivityQuery query : ActivityQueryHelper.APPS_BY_CATEGORY) {exemptedActivities.addAll(Arrays.asList(query.run(this.getDevice())));}//------------step2final Set<String> exemptedPackages = new HashSet<String>();exemptedPackages.addAll(this.readExemptions("gallery_exemptions"));exemptedPackages.addAll(this.readExemptions("streaming_music_apps"));exemptedPackages.addAll(this.readExemptions("streaming_video_apps"));exemptedPackages.addAll(this.readExemptions("all_apps_memory_exemptions"));final List<String> activityList = new ArrayList<String>(Arrays.asList(activities));//------------step3final Iterator<String> it = activityList.iterator();while (it.hasNext()) {final String activity = it.next();final String packageName = activity.split("/")[0];if (exemptedPackages.contains(packageName)) {LogUtil.CLog.d("exempt package " + packageName);it.remove();}else {if (!exemptedActivities.contains(activity)) {continue;}LogUtil.CLog.d("exempt activity " + activity);it.remove();}}//------------step4LogUtil.CLog.d("These apps will be checked: " + String.join(",", activityList));//------------step5final long maxPeakPssAllowed = this.calculateMaxAllowedPeakPssUsage("max_memory_all_apps");final StringBuilder violations = new StringBuilder();for (final String activity2 : activityList) {//------------step6final String packageName2 = activity2.split("/")[0];this.runPostNotificationPermissionTest("grantRuntimePermission", packageName2);final String amOutput = this.getDevice().executeShellCommand(this.buildStartActivityCommand(activity2, 268468224));Assert.assertTrue(activity2 + " failed to start", amOutput.contains("Status: ok"));TimeUnit.SECONDS.sleep(30L);if (this.shouldExemptTopActivity(exemptedActivities)) {continue;}//------------step7final long memoryKb = this.getMemoryUsage(packageName2);this.stopApplication(packageName2);if (memoryKb >= maxPeakPssAllowed) {violations.append(packageName2).append(" ").append(memoryKb).append(",");}this.runPostNotificationPermissionTest("revokeRuntimePermission", packageName2);}//------------step8if (violations.length() > 0) {violations.append(" failed to keep to the max pss of ");violations.append(maxPeakPssAllowed);Assert.fail(violations.toString());}}

源码比较多,都封装在 GtsMemoryHostTestCases.jar 中。这里只是来看下 test 接口。

step1. 查找所有符合要求的activity

通过 ActivityQueryHelper.ALL_APPS_QUERY 来查询所有符合条件的 activities:

ActivityQueryHelper.javaALL_APPS_QUERY = new ActivityQuery().setAction("android.intent.action.MAIN").setCategory("android.intent.category.LAUNCHER");

要求Action 为 android.intent.action.MAIN,category 为 android.intent.category.LAUNCHER 的所有 Activities。

step2. 确定免除的package

        final Set<String> exemptedPackages = new HashSet<String>();exemptedPackages.addAll(this.readExemptions("gallery_exemptions"));exemptedPackages.addAll(this.readExemptions("streaming_music_apps"));exemptedPackages.addAll(this.readExemptions("streaming_video_apps"));exemptedPackages.addAll(this.readExemptions("all_apps_memory_exemptions"));

这些可以免除的 package 都定义在 GtsMemoryHostTestCases.dynamic 文件中。

step3. 轮询确定最终的activity

被免除的应用会在 log 中打印出来:

09-14 10:02:54 D/AllAppsMemoryHostTest: exempt activity com.android.chrome/com.google.android.apps.chrome.Main
09-14 10:02:54 D/AllAppsMemoryHostTest: exempt activity com.google.android.apps.photosgo/.home.HomeActivity
09-14 10:02:54 D/AllAppsMemoryHostTest: exempt package com.google.android.youtube
09-14 10:02:54 D/AllAppsMemoryHostTest: exempt activity org.codeaurora.dialer/com.android.dialer.main.impl.MainActivity
09-14 10:02:54 D/AllAppsMemoryHostTest: exempt package com.google.android.apps.nbu.files

step4. 确定最终可以check 的activity

在经过 step3 之后,log 中会打印出最终需要 check 的acitivity:

09-14 10:02:54 D/AllAppsMemoryHostTest: These apps will be checked: com.android.mms/.ui.ConversationList,
com.android.settings/.Settings,
com.android.soundrecorder/.SoundRecorder,
com.android.vending/.AssetBrowserActivity,
com.google.android.apps.assistant/.go.MainActivity,
com.google.android.apps.messaging/.ui.ConversationListActivity,
com.google.android.apps.tachyon/.MainActivity,
com.google.android.calculator/com.android.calculator2.Calculator,
com.google.android.calendar/com.android.calendar.AllInOneActivity,
com.google.android.contacts/com.android.contacts.activities.PeopleActivity,
com.google.android.deskclock/com.android.deskclock.DeskClock,
com.google.android.dialer/.extensions.GoogleDialtactsActivity,
org.codeaurora.snapcam/com.android.camera.CameraLauncher,
com.caf.fmradio/.FMRadio,
com.google.android.apps.mapslite/com.google.maps.lite.twa.MapsLiteTwaLauncherActivity,
com.google.android.apps.searchlite/.ui.SearchActivity

 step5. 确定设备的 layout size,并确定peakPss

设备的layout size 在《GTS 中testPersistentProcessMemory fail 详解》一文中已经分析过,详细看第 2.1 节。

这里最终根据 layout size 确定 peakPss,该属性值都定义  GtsMemoryHostTestCases.dynamic 文件中:

    ...<entry key="max_memory_all_apps_2gb_hd"><value>153600</value></entry>...

step6. 轮询待check的activities,确定package name,并申请 android.permission.POST_NOTIFICATIONS 权限。

step7. 确定进程内存,并关闭notification 权限

通过 dumpsys -t 30 meminfo --package packageName 的命令确定进程内存,依然通过 Pattern 类确定内存:

        final List<String> usages = new ArrayList<String>();final Matcher matcher = Pattern.compile("TOTAL\\s+([\\d]+)").matcher(output);while (matcher.find()) {usages.add(matcher.group(1));}Assert.assertFalse("Could not get meminfo total for " + packageName, usages.isEmpty());return usages.stream().mapToLong((ToLongFunction<? super Object>)Long::valueOf).sum();

step8. 统计超过 max pss

如果有进程的 memory 超过了 peakPss,则会打印显示

3. 解决方案

本文中的 error log 从host log 中比较清晰:

09-14 10:12:33 W/NativeDevice: Command: 'shell am start -W -S -f 10008000 'com.google.android.apps.mapslite/com.google.maps.lite.twa.MapsLiteTwaLauncherActivity'' on 'd4081bc5' went over its timeout for outputing a response.
09-14 10:14:34 W/NativeDevice: Command: 'shell am start -W -S -f 10008000 'com.google.android.apps.mapslite/com.google.maps.lite.twa.MapsLiteTwaLauncherActivity'' on 'd4081bc5' went over its timeout for outputing a response.
09-14 10:16:34 W/NativeDevice: Command: 'shell am start -W -S -f 10008000 'com.google.android.apps.mapslite/com.google.maps.lite.twa.MapsLiteTwaLauncherActivity'' on 'd4081bc5' went over its timeout for outputing a response.
09-14 10:16:34 I/TestFailureListener: FailureListener.testFailed com.google.android.memory.gts.AllAppsMemoryHostTest#testPeakPssOfAllApps false...09-14 10:16:34 W/GranularRetriableTestWrapper: com.android.tradefed.device.DeviceUnresponsiveException[DEVICE_UNRESPONSIVE|520751|LOST_SYSTEM_UNDER_TEST]: Attempted shell am start -W -S -f 10008000 'com.google.android.apps.mapslite/com.google.maps.lite.twa.MapsLiteTwaLauncherActivity' multiple times on device d4081bc5 without communication success. Aborting.

根本原因是启动这个 acitivity 没有返回 Staatus: ok 的状态

 

 

 

 

相关文章:

GTS 中testPeakPssOfAllApps fail 详解

0. 前言 GTS 在测试 case armeabi-v7a GtsMemoryHostTestCases 的时候出现下面异常&#xff0c;本文总结一下。 com.google.android.memory.gts.AllAppsMemoryHostTest#testPeakPssOfAllApps 1. error log 09-14 10:16:34 I/TestFailureListener: FailureListener.testFaile…...

linux查看远程仓库的分支

在 Linux 终端中&#xff0c;您可以使用 git 命令来查看远程仓库的分支。git 是版本控制系统&#xff0c;用于管理代码的版本和协作开发。以下是查看远程仓库分支的方法&#xff1a; 查看所有远程分支&#xff1a; git ls-remote <remote_repository_url> 这个命令会显示…...

【Linux常用命令】

编程不良人 Linux 笔记 一、防火墙相关 1、查看防火墙状态 systemctl status flrewalld2、如果防火墙是开启状态的&#xff0c;需要关闭 systemctl stop firewalld3、永久行关闭操作&#xff08;禁止开机自启动&#xff09; 因为防火默认是开启状态的&#xff0c;如果只是手…...

QString类与整型,浮点数互转

本文介绍QString类与整型&#xff0c;浮点数之间的相互转换。 1.QString类转整型 QString类转整型&#xff08;包含2进制&#xff0c;8进制&#xff0c;16进制&#xff09;&#xff0c;可以使用QString的toInt()函数。 QString str("1234"); bool bOK false; int…...

基于STM32F407ZET6的环境温湿度监控系统(粤嵌GEC-M4)

注意使用事项&#xff1a; 开发板如下 由于外部晶振是8M&#xff0c;需要修改setup和stm32f4头文件的晶振值。 操作如下&#xff1a; system_stm32f4xx.c的254行 #define PLL_M 8stm32f4xx.h的127行 #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the Ex…...

2023年五一杯数学建模A题无人机定点投放问题求解全过程论文及程序

2023年五一杯数学建模 A题 无人机定点投放问题 原题再现&#xff1a; 随着科学技术的不断发展&#xff0c;无人机在许多领域都有着广泛的应用。对于空中执行定点投放任务的无人机&#xff0c;其投放精度不仅依赖于无人机的操作技术&#xff0c;而且还与无人机执行任务时所处状…...

Redis 7 第九讲 微服务集成Redis 应用篇

Jedis 理论 Jedis是redis的java版本的客户端实现&#xff0c;使用Jedis提供的Java API对Redis进行操作&#xff0c;是Redis官方推崇的方式&#xff1b;并且&#xff0c;使用Jedis提供的对Redis的支持也最为灵活、全面&#xff1b;不足之处&#xff0c;就是编码复杂度较高。 …...

c++day7

仿照vector手动实现自己的myVector&#xff0c;最主要实现二倍扩容功能 #include <iostream>using namespace std; template <typename T> class Myvector { private:T *start;//起始指针T *end;//数组末尾指针T *last;//数组有效长度的尾指针 public://定义无参构…...

C++学习概述

1.c 为啥需要头文件 如果您刚开始使用 C&#xff0c;您可能想知道为什么C需要 #include 头文件&#xff0c;以及为什么一个程序要拥有多个 .cpp 文件。 原因很简单&#xff1a; a) 减少编译时间 随着程序的增长&#xff0c;您的代码也会增长&#xff0c;如果所有内容都在一个…...

关系型数据库和非关系型数据库

关系型数据库和非关系型数据库 关系型数据库非关系型数据库 非关系型数据库和关系型数据库是两种不同类型的数据库管理系统&#xff0c;它们用于存储和管理数据&#xff0c;但在数据组织和处理方式上有一些重要的区别。 关系型数据库 1.结构化数据存储&#xff1a;关系型数据库…...

基于SSM的快餐店点餐服务系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…...

使用vcpkg配置CGAL+visual studio 2022

先安装vcpkg C:\dev> git clone https://github.com/microsoft/vcpkg C:\dev> cd vcpkg C:\dev\vcpkg> .\bootstrap-vcpkg.bat 运行后&#xff0c;先执行 C:\dev\vcpkg> .\vcpkg.exe install yasm-tool:x86-windows 这是因为gmp库中有个bug&#xff0c;只能这样…...

【Spring面试】三、Bean的配置、线程安全、自动装配

文章目录 Q1、什么是Spring Bean&#xff1f;和对象有什么区别Q2、配置Bean有哪几种方式&#xff1f;Q3、Spring支持的Bean有哪几种作用域&#xff1f;Q4、单例Bean的优势是什么&#xff1f;Q5、Spring的Bean是线程安全的吗&#xff1f;Q6、Spring如何处理线程并发问题&#xf…...

flink连接kafka报:org.apache.kafka.common.errors.TimeoutException

测试flink1.12.7 连接kafka&#xff1a; package org.test.flink;import org.apache.flink.api.common.serialization.SimpleStringSchema; import org.apache.flink.streaming.api.datastream.DataStream; import org.apache.flink.streaming.api.environment.StreamExecutio…...

sql order by 排序 null值放最后,怎么写

在 SQL 中&#xff0c;可以使用 ORDER BY 子句对结果进行排序。如果要将 NULL 值放在最后&#xff0c;可以在排序列中使用 CASE 表达式来处理。 下面是一个示例查询&#xff0c;将 NULL 值放在最后进行排序&#xff1a; SELECT column1, column2 FROM your_table ORDER BY CAS…...

HDMI字符显示实验

FPGA教程学习 第十五章 HDMI字符显示实验 文章目录 FPGA教程学习前言实验原理程序设计像素点坐标模块字符叠加模块 实验结果知识点总结 前言 在HDMI输出彩条的基础上输出osd叠加信息。 实验原理 实验通过字符转换工具将字符转换为 16 进制 coe 文件存放到单端口的 ROM IP 核…...

Spring Cloud 框架搭建

Spring Cloud 框架搭建之一基础框架 创建父项目创建子项目 创建父项目 第一步&#xff1a;新建项目&#xff0c;填写基础信息 第二步&#xff1a;这里不需要其他组件直接点next即可。 第三步&#xff1a;pom文件添加下述代码&#xff0c;将父项目设置为pom文件形式打包&#…...

20个非常有用的单行Python代码片段

1. 写在前面 继上篇&#xff0c;继续在本文分享 20 个 Python 单行代码&#xff0c;可以在 30 秒或更短时间内轻松学会。这些单行代码不仅可以提高效率&#xff0c;同时使代码看起来更整洁、更易读。&#xff1a;&#xff09; 个人博客&#xff1a; https://jianpengzhang.git…...

【LangChain系列 9】Prompt模版——MessagePromptTemplate

原文地址&#xff1a;【LangChain系列 9】Prompt模版——MessagePromptTemplate 本文速读&#xff1a; MessagePromptTemplate MessagesPlaceholder 在对话模型(chat model) 中&#xff0c; prompt主要是封装在Message中&#xff0c;LangChain提供了一些MessagePromptTemplat…...

ROS2的学习路径

学习ROS2的建议学习路径&#xff1a; 理解基础知识&#xff1a; 熟悉机器人操作系统&#xff08;ROS&#xff09;的概念及其架构。了解ROS2相对于ROS1的优势以及其提供的关键功能。 安装和配置&#xff1a; 在你选择的操作系统上安装ROS2&#xff08;如Ubuntu、Windows、macOS…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈

在日常iOS开发过程中&#xff0c;性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期&#xff0c;开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发&#xff0c;但背后往往隐藏着系统资源调度不当…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

怎么让Comfyui导出的图像不包含工作流信息,

为了数据安全&#xff0c;让Comfyui导出的图像不包含工作流信息&#xff0c;导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo&#xff08;推荐&#xff09;​​ 在 save_images 方法中&#xff0c;​​删除或注释掉所有与 metadata …...

Kafka主题运维全指南:从基础配置到故障处理

#作者&#xff1a;张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1&#xff1a;主题删除失败。常见错误2&#xff1a;__consumer_offsets占用太多的磁盘。 主题日常管理 …...