Android system_server进程
目录
一、system_server进程介绍
二、system_server进程启动流程
2.1 startBootstrapServices
2.2 startCoreServices
2.3 startOtherServices
2.4 startApexServices
三、如何使用系统服务
3.1 app进程调用系统服务
3.2 native进程调用系统服务
3.3 system_server进程中两个服务之间的调用
四、如何添加一个系统服务
五、如何裁剪系统服务
六、其它模块
6.1 NativeCrashListener
6.2 Android watchdog
一、system_server进程介绍
Android system_server进程由zygote进程fork创建,是framework层的核心进程,主要由ASM、PMS等系统服务组成,给app提供Binder调用、与native & hal进程通信。
二、system_server进程启动流程
system_server进程启动入口:
// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String[] argv) {...if (startSystemServer) {Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);}...
}private static Runnable forkSystemServer(String abiList, String socketName,ZygoteServer zygoteServer) {...pid = Zygote.forkSystemServer(parsedArgs.mUid, parsedArgs.mGid,parsedArgs.mGids,parsedArgs.mRuntimeFlags,null,parsedArgs.mPermittedCapabilities,parsedArgs.mEffectiveCapabilities);...
}// frameworks/base/core/java/com/android/internal/os/Zygote.java
static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {ZygoteHooks.preFork();int pid = nativeForkSystemServer(uid, gid, gids, runtimeFlags, rlimits,permittedCapabilities, effectiveCapabilities);// Set the Java Language thread priority to the default value for new apps.Thread.currentThread().setPriority(Thread.NORM_PRIORITY);ZygoteHooks.postForkCommon();return pid;
}// frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
static jint com_android_internal_os_Zygote_nativeForkSystemServer(JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities,jlong effective_capabilities) {...// fork出system_server子进程pid_t pid = zygote::ForkCommon(env, true, fds_to_close, fds_to_ignore, true);// 通过JNI调用SystemServer类的main方法if (pid == 0) {SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, permitted_capabilities,effective_capabilities, MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true,false, nullptr, nullptr, /* is_top_app= */ false,/* pkg_data_info_list */ nullptr,/* allowlisted_data_info_list */ nullptr, false, false);} else if (pid > 0) {...}return pid;
}
通过JNI调用SystemServer类的main方法:
// frameworks/base/services/java/com/android/server/SystemServer.java public static void main(String[] args) {...new SystemServer().run();
}private void run() {...// Start services.startBootstrapServices(t);startCoreServices(t);startOtherServices(t);startApexServices(t);updateWatchdogTimeout(t); ...
}
2.1 startBootstrapServices
启动系统最重要的服务,执行startService和startBootPhase方法,如下:
// frameworks/base/services/java/com/android/server/SystemServer.java private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {// 启动watchdog线程final Watchdog watchdog = Watchdog.getInstance();watchdog.start();...// 启动AMSActivityTaskManagerService atm = mSystemServiceManager.startService(ActivityTaskManagerService.Lifecycle.class).getService();mActivityManagerService = ActivityManagerService.Lifecycle.startService(mSystemServiceManager, atm);mActivityManagerService.setSystemServiceManager(mSystemServiceManager);mActivityManagerService.setInstaller(installer);mWindowManagerGlobalLock = atm.getGlobalLock();// 启动PMSmPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);// 启动ThermalManagerServicemSystemServiceManager.startService(ThermalManagerService.class);...mSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);}
startService:通过反射的方式调用服务的onStart方法,
// frameworks/base/services/core/java/com/android/server/SystemServiceManager.javapublic <T extends SystemService> T startService(Class<T> serviceClass) {final String name = serviceClass.getName();// Create the service.if (!SystemService.class.isAssignableFrom(serviceClass)) {throw new RuntimeException("Failed to create " + name+ ": service must extend " + SystemService.class.getName());}final T service;try {Constructor<T> constructor = serviceClass.getConstructor(Context.class);service = constructor.newInstance(mContext);}...startService(service);return service;
}public void startService(@NonNull final SystemService service) {// Check if already startedString className = service.getClass().getName();if (mServiceClassnames.contains(className)) {Slog.i(TAG, "Not starting an already started service " + className);return;}mServiceClassnames.add(className);// Register it.mServices.add(service);// Start it.long time = SystemClock.elapsedRealtime();try {service.onStart();}
}
PMS服务执行onStart和startBootPhase方法:
public void onStart() {publishBinderService(Context.POWER_SERVICE, mBinderService, /* allowIsolated= */ false,DUMP_FLAG_PRIORITY_DEFAULT | DUMP_FLAG_PRIORITY_CRITICAL);publishLocalService(PowerManagerInternal.class, mLocalService);Watchdog.getInstance().addMonitor(this);Watchdog.getInstance().addThread(mHandler);
}@Override
public void onBootPhase(int phase) {if (phase == PHASE_SYSTEM_SERVICES_READY) {systemReady();} else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {incrementBootCount();} else if (phase == PHASE_BOOT_COMPLETED) {synchronized (mLock) {...}...
}
服务名称 | 作用 | |
1 | ArtModuleServiceInitializer | 初始化 ART 模块服务管理器 |
2 | Watchdog | 系统守护线程,监听系统服务是否发生死锁 |
3 | platformCompat | 平台兼容性服务,为其他服务提供兼容性支持 |
4 | FileIntegrityService | 文件完整性服务,响应应用和系统的完整性请求 |
5 | Installer | 安装器服务,等待 Installd 启动完成 |
6 | DeviceIdentifiersPolicyService | 设备标识符策略服务,注册在启动应用程序管理器之前 |
7 | UriGrantsManagerService | URI 授权管理服务 |
8 | PowerStatsService | 电源统计数据跟踪服务 |
9 | MemtrackProxyService | 内存跟踪代理服务,早于 ActivityManagerService 启动 |
10 | AccessCheckingService | 访问检查服务,提供新的权限和应用操作实现 |
11 | ActivityManagerService | 系统核心服务,管理活动和任务 |
12 | DataLoaderManagerService | 数据加载器管理服务 |
13 | IncrementalService | 增量安装服务 |
14 | PowerManagerService | 电源管理服务 |
15 | ThermalManagerService | 热管理服务 |
16 | HintManagerService | 提示管理服务 |
17 | RecoverySystemService | 设备进入Recovery模式时提供各种功能和操作 |
18 | LightsService | LED 和显示背光管理服务 |
19 | DisplayOffloadService | 显示卸载服务 |
20 | SidekickService | SidekickService服务通常与其他应用程序一起工作,为用户提供额外的功能和支持 |
21 | DisplayManagerService | 显示管理器服务 |
22 | DomainVerificationService | selinux权限验证服务 |
23 | PackageManagerService | 包管理器服务,管理应用程序包和应用程序 |
24 | DexUseManagerLocal | 本地 Dex 使用管理器 |
25 | OtaDexOptService | A/B OTA dexopt 管理服务 |
26 | UserManagerService | 用户管理服务 |
27 | OverlayManagerService | 用于管理和处理窗口覆盖(Overlay)相关的操作 |
28 | ResourcesManagerService | 资源管理器服务 |
29 | SensorPrivacyService | 传感器隐私管理服务 |
30 | SensorService | 传感器服务 |
2.2 startCoreServices
启动系统核心服务,如下:
private void startCoreServices(@NonNull TimingsTraceAndSlog t) {...mSystemServiceManager.startService(SystemConfigService.class);mSystemServiceManager.startService(BatteryService.class);mSystemServiceManager.startService(UsageStatsService.class);mActivityManagerService.setUsageStatsManager(LocalServices.getService(UsageStatsManagerInternal.class));mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);mSystemServiceManager.startService(CachedDeviceStateService.class);mSystemServiceManager.startService(BinderCallsStatsService.LifeCycle.class);mSystemServiceManager.startService(LooperStatsService.Lifecycle.class);mSystemServiceManager.startService(ROLLBACK_MANAGER_SERVICE_CLASS);mSystemServiceManager.startService(NativeTombstoneManagerService.class);mSystemServiceManager.startService(BugreportManagerService.class);mSystemServiceManager.startService(GpuService.class);mSystemServiceManager.startService(RemoteProvisioningService.class);mSystemServiceManager.startService(CpuMonitorService.class);}
服务名称 | 作用 | |
1 | SystemConfigService | 用于管理和提供系统级别的配置信息。SystemConfigService服务为应用程序和系统组件提供了一种访问系统配置信息的方式 |
2 | BatteryService | 用于管理和提供电池相关的信息和功能。BatteryService服务为应用程序和系统组件提供了一种访问电池状态和控制电池使用的方式 |
3 | WebViewUpdateService | 用于管理和提供WebView组件的更新信息。WebView是Android系统中的一个内置组件,用于在应用程序中显示和处理网页内容 |
4 | CachedDeviceStateService | 用于缓存和提供设备状态信息。这个服务会在设备启动时创建,并在整个系统运行过程中提供设备状态信息 |
5 | BinderCallsStatsService | 为系统提供了一种收集和分析Binder通信性能数据的服务 |
6 | LooperStatsService | 为系统提供了一种收集和分析Looper线程性能数据的服务 |
7 | RollbackManagerService | 为系统提供了一种管理和实现系统回滚功能的方式,以便在出现问题时快速恢复系统状态 |
8 | NativeTombstoneManagerService | 为系统提供了一种管理和收集Native堆栈Tombstone信息,以便在进程发生native crash时快速定位问题 |
9 | BugreportManagerService | 为系统提供了一种管理和实现Bugreport信息,以便在需要时快速收集系统和程序状态信息 |
10 | GpuService | 为系统提供了一种访问GPU信息和控制GPU使用的服务 |
11 | RemoteProvisioningService | 为系统提供了一种管理和实现远程设备配置功能,以便在需要时远程配置设备 |
12 | CpuMonitorService | 用于管理和提供CPU相关的信息和功能 |
2.3 startOtherServices
启动系统其它的服务,如下:
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {...mSystemServiceManager.startService(DropBoxManagerService.class);mSystemServiceManager.startService(ALARM_MANAGER_SERVICE_CLASS);mSystemServiceManager.startService(CameraServiceProxy.class);WindowManagerService.main(context, inputManager, !mFirstBoot,pwm, mActivityManagerService.mActivityTaskManager);// 这类系统服务可以做裁剪 if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_PRINTING)) {t.traceBegin("StartPrintManager");mSystemServiceManager.startService(PRINT_MANAGER_SERVICE_CLASS);t.traceEnd();}}if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_COMPANION_DEVICE_SETUP)) {t.traceBegin("StartCompanionDeviceManager");mSystemServiceManager.startService(COMPANION_DEVICE_MANAGER_SERVICE_CLASS);t.traceEnd();// VirtualDeviceManager depends on CDM to control the associations.t.traceBegin("StartVirtualDeviceManager");mSystemServiceManager.startService(VIRTUAL_DEVICE_MANAGER_SERVICE_CLASS);t.traceEnd();}...// 这里会启动launcher进程mActivityManagerService.systemReady(() -> { ...}...// 启动systemuistartSystemUi(context, windowManagerF);...
}
服务名称 | 作用 | |
1 | KeyChainSystemService | 用于管理和提供密钥链(KeyChain)相关的信息和功能。密钥链是一种在Android系统中存储和管理敏感信息(如密码、密钥等)的机制,通常用于实现设备安全、数据加密等场景。 |
2 | DropBoxManagerService | app进程发生ANR、native crash时,收集相关debug信息 |
3 | ContentService | 为系统提供了一种管理和实现ContentProvider功能的方式,以便在需要时实现数据共享和访问 |
4 | AlarmManagerService | 定时任务 |
5 | InputManagerService | 管理和提供输入设备相关的信息和功能 |
6 | DeviceStateManagerService | 用于管理设备的状态信息 |
7 | WindowManagerService | 负责管理设备上的窗口和界面。它为应用程序提供了一个统一的接口,用于创建、显示、隐藏、移动、调整大小等操作窗口。 |
8 | BluetoothService | 理蓝牙设备的连接和通信。它提供了一系列API,允许应用程序通过蓝牙进行数据交换、文件传输、音频流传输等操作。 |
9 | StorageManagerService | 负责管理设备的存储空间。它为应用程序提供了一个统一的接口,用于访问设备的内部存储(如闪存)和外部存储(如SD卡)。 |
10 | OemLockService | 管理设备的OEM锁定状态 |
11 | DeviceIdleController | 管理设备的空闲状态。当设备处于空闲状态时,DeviceIdleController可以自动执行一些节能措施,如降低屏幕亮度、关闭无线网络等,以延长设备的电池寿命。 |
12 | DevicePolicyManagerService | 管理设备的策略和安全设置。 |
13 | StatusBarManagerService | 管理设备的状态栏。它提供了一系列API,允许应用程序在状态栏上显示通知、图标、进度条等信息。 |
14 | NetworkManagementService | 管理设备的网络连接。它提供了一系列API,允许应用程序获取设备的网络状态、连接类型、IP地址等信息,并可以控制设备的网络连接。 |
15 | NetworkStatsService | 统计设备的网络使用情况。它提供了一系列API,允许应用程序获取设备的网络流量统计信息,如总流量、各个应用程序的流量等。 |
16 | NetworkPolicyManagerService | 管理设备的网络策略。它提供了一系列API,允许设备管理员对设备的网络连接进行策略管理,如限制应用程序的网络访问、设置网络优先级等。 |
17 | SystemUpdateManagerService | 管理设备的系统更新。它提供了一系列API,允许对设备的系统更新进行管理,如检查系统更新、下载系统更新、安装系统更新等。 |
18 | NotificationManagerService | 管理设备的通知。它提供了一系列API,允许应用程序在通知栏上显示通知,如消息通知、提醒通知等。 |
19 | DeviceStorageMonitorService | 监控设备的存储空间。它提供了一系列API,允许应用程序获取设备的存储空间信息,如总容量、已用容量、可用容量等。 |
20 | AudioService | 管理设备的音频。允许应用程序控制设备的音频输出,如播放音乐、播放铃声等。 |
21 | BroadcastRadioService | 管理设备的广播电台。允许应用程序接收广播电台的节目,如新闻、音乐等。 |
22 | AdbService | 管理设备的ADB连接。允许开发人员通过ADB连接设备,进行调试和测试。 |
23 | UsbService | 管理设备的USB连接。允许应用程序通过USB连接设备,进行数据传输和通信 |
24 | GestureLauncher | 用于识别和响应用户的手势操作。允许应用程序检测和响应用户的手势操作,如滑动、捏合、旋转等。 |
25 | SensorNotificationService | 管理设备的传感器通知。允许应用程序获取设备的传感器信息,如加速度计、陀螺仪等 |
26 | DiskStatsService | 管理设备的磁盘状态。允许应用程序获取设备的磁盘状态信息,如分区大小、使用情况等。 |
27 | RuntimeService | 管理设备的运行时环境。允许应用程序获取设备的运行时信息,如内存使用情况、CPU使用情况等。 |
28 | GraphicsStatsService | 管理设备的图形性能 |
29 | FaceSensorService | 管理设备的面部识别功能 |
30 | HealthService | 用于管理设备的健康状态。允许应用程序获取设备的健康状态信息,如电池电量、温度等。 |
31 | SdkSandboxManagerService | 管理设备的SDK沙盒环境。允许应用程序获取设备的SDK沙盒信息,如应用程序的权限、资源等。 |
32 | PermissionPolicyService | 管理设备的权限策略 |
33 | LockSettingsService | 管理设备的锁定设置,如屏幕锁定方式、密码等。 |
34 | LauncherAppsService | 管理设备的启动器应用程序。允许应用程序获取设备的启动器应用程序信息,如启动器应用程序的名称、图标等。 |
35 | AppServiceManager | 管理设备的应用程序服务 |
36 | GameManagerService | 用于管理游戏的运行和状态 |
37 | LocationManagerService | 用于管理设备的位置信息,允许应用程序获取设备的位置信息,如经纬度、海拔等 |
38 | FingerprintSensor | 管理设备的指纹识别功能 |
39 | IoTSystemService | 理设备的物联网功能 |
40 | SafetyCenterService | 理设备的安全功能。允许应用程序获取设备的安全信息,如病毒扫描、防火墙等 |
其它系统服务: KeyAttestationApplicationIdProviderService、BinaryTransparencyService、SchedulingPolicyService、TelecomLoaderService、TelephonyRegistry、EntropyMixer、AccountManagerService、InstallSystemProviders、 RoleManagerService、VibratorManagerService、DynamicSystemService、ConsumerIrService、ResourceEconomy、 CameraServiceProxy、VrManagerService、IpConnectivityMetrics、NetworkWatchlistService、PinnerService、 ProfcollectForwardingService、SignedConfigService、AppIntegrityService、LogcatManagerService、 InputMethodManagerService、AccessibilityManagerService、UiModeManagerService、LocaleManagerService、 GrammaticalInflectionService、AppHibernationService、LockSettingsService、PersistentDataBlockService、 MusicRecognitionManagerService、SpeechRecognitionManagerService、AppPredictionService、 ContentSuggestionsService、SearchUiService、SmartspaceService、FontManagerService、TextServicesManager、 TextClassificationManagerService、NetworkScoreService、RttService、WifiAwareService、WifiP2PService、 LowpanService、PacProxyService、ConnectivityService、MiCarNetService、VpnManagerService、VcnManagementService、UpdateLockService、TimeDetectorService、CountryDetectorService、 TimeZoneDetectorService、AltitudeService、LocationTimeZoneManagerService、GnssTimeUpdateService、 SearchManagerService、WallpaperManagerService、WallpaperEffectsGenerationService、SoundTriggerMiddlewareService、DockObserver、ThermalObserver、WiredAccessoryManagerService、 MidiManagerService、SerialService、HardwarePropertiesManagerService、TwilightService、ColorDisplayService、 SoundTriggerService、TrustManagerService、BackupManager、AppWidgetService、VoiceRecognitionManager、 ContextHubSystemService、NetworkTimeUpdateService、EmergencyAffordanceService、DreamManagerService、 CoverageService、PrintManager、AttestationVerificationService、CompanionDeviceManager、VirtualDeviceManager、RestrictionManager、MediaSessionService、HdmiControlService、TvInteractiveAppManager、TvInputManager、TunerResourceManager、MediaResourceMonitor、 TvRemoteService、MediaRouterService、IrisSensor、FingerprintSensor、BiometricService、 AuthService、DynamicCodeLoggingService、PruneInstantAppsJobService、ShortcutService、 CrossProfileAppsService、PeopleService、MediaMetricsManager、BackgroundInstallControlService、 MediaProjectionManager、WearPowerService、WearConnectivityService、WearDisplayService、 WearTimeService、WearGlobalActionsService、SliceManagerService、 StatsCompanion、StatsPullAtomService、BootstrapAtomService、IncidentCompanionService、 AdServicesManagerService、OnDevicePersonalizationSystemService、MmsService、AutoFillService、 CredentialManagerService、TranslationManagerService、SelectionToolbarManagerService、ClipboardService、 TracingServiceProxy、DeviceSpecificServices、MediaCommunicationService、 AppCompatOverridesService、HealthConnectManagerService等 |
2.4 startApexServices
启动系统apex服务,如下:
private void startApexServices(@NonNull TimingsTraceAndSlog t) {List<ApexSystemServiceInfo> services = ApexManager.getInstance().getApexSystemServices();for (ApexSystemServiceInfo info : services) {String name = info.getName();String jarPath = info.getJarPath();t.traceBegin("starting " + name);if (TextUtils.isEmpty(jarPath)) {mSystemServiceManager.startService(name);} else {mSystemServiceManager.startServiceFromJar(name, jarPath);}t.traceEnd();}}
三、如何使用系统服务
3.1 app进程调用系统服务
以PMS服务为例,app进程通过获取PMS服务代理---PowerManager对象,调用PowerManager中的接口:
// 获取PowerManager实例
PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
// 调用PowerManager类中的接口
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLockTag");
3.2 native进程调用系统服务
通过binder对parcel数据通信:
#include <binder/IServiceManager.h>
#include <binder/Parcel.h>sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("power"));
if (!binder) {return EXIT_FAILURE;
}
Parcel data, result;
data.writeInterfaceToken(String16("android.os.IPowerManager"));
char d[] = {0x00};
data.write(d, sizeof(d));
// 6表示对应的方法ID
binder->transact(6, data, &result);
或者直接调用binder接口:
#include <binder/IActivityManager.h>
#include <binder/IBinder.h>
#include <binder/IServiceManager.h>int openContentProviderFile(const String16& uri)
{int fd = -1;sp<IServiceManager> sm = defaultServiceManager();sp<IBinder> binder = sm->getService(String16("activity"));sp<IActivityManager> am = interface_cast<IActivityManager>(binder);if (am != NULL) {fd = am->openContentUri(uri);}return fd;
}
3.3 system_server进程中两个服务之间的调用
system_server进程中的服务间调用属于进程内部通信。如PMS服务启动时会将内部的mLocalService对象注册到本地service管理中,对外提供一个PowerManagerInternal类及接口,给其它服务调用,如下:
// 其它服务中通过获取PowerManagerInternal对象,调用接口
private PackageManagerInternal mPackageManagerInternal;mLocalPowerManager = getLocalService(PowerManagerInternal.class);
mLocalPowerManager.getLowPowerState(ServiceType.QUICK_DOZE).batterySaverEnabled);// frameworks/base/core/java/android/os/PowerManagerInternal.java
// 抽象方法,在具体实现类中实现
public abstract PowerSaveState getLowPowerState(int serviceType);// frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
public final class PowerManagerService extends SystemServiceimplements Watchdog.Monitor {...@Overridepublic void onStart() {// 注册到servicemanager中,用于进程间通信publishBinderService(Context.POWER_SERVICE, mBinderService, /* allowIsolated= */ false,DUMP_FLAG_PRIORITY_DEFAULT | DUMP_FLAG_PRIORITY_CRITICAL);// 加入到本地service中,用于进程内部调用 publishLocalService(PowerManagerInternal.class, mLocalService);...}// 内部类继承PowerManagerInternal,并实现父类抽象方法final class LocalService extends PowerManagerInternal {...@Overridepublic PowerSaveState getLowPowerState(@ServiceType int serviceType) {return mBatterySaverPolicy.getBatterySaverPolicy(serviceType);}...}...
}
四、如何添加一个系统服务
添加步骤:
1)准备系统服务代码DemoSystemService.java和Android.bp文件
// 继承SystemService,实现Watchdog.Monitor接口
public final class DemoManagerService extends SystemServiceimplements Watchdog.Monitor {// 服务名称为 "demo"String SERVICE_NAME = "demo";...// 重写onStart和onBootPhase方法@Overridepublic void onStart() {// 发布服务publishBinderService(SERVICE_NAME, mBinderService, /* allowIsolated= */ false,DUMP_FLAG_PRIORITY_DEFAULT | DUMP_FLAG_PRIORITY_CRITICAL);// 用于监控DemoManagerService是否发生死锁Watchdog.getInstance().addMonitor(this);Watchdog.getInstance().addThread(mHandler);}@Overridepublic void onBootPhase(int phase) {...}...
}
filegroup {name: "demo--system-service-sources",srcs: ["DemoSystemService.java"],
}
2)将services.jar模块编译依赖新增模块
修改frameworks/base/services/Android.bp,如下:
java_library {name: "services",...srcs: [":services-main-sources",":demo--system-service-sources"],...
}
3)SystemServer.java中启动Demo服务
修改frameworks/base/services/java/com/android/server/SystemServer.java, 启动DemoSystemService,如下:
public final class SystemServer implements Dumpable {...private void startOtherServices(@NonNull TimingsTraceAndSlog t) {t.traceBegin("StartDemoSystemService");mSystemServiceManager.startService(DemoSystemService.class);t.traceEnd();}...
}
4)添加selinux规则
修改system/sepolicy库,添加demo服务的标签和规则,注意添加的服务名称为demo,如下:
// system/sepolicy/private/compat/32.0/32.0.ignore.cil
vendor_vm_file
virtual_device_service
wallpaper_effects_generation_service
demo_service// system/sepolicy/prebuilts/api/32.0/private/service_contexts
demo u:object_r:demo_service:s0// system/sepolicy/prebuilts/api/32.0/public/service.te
type demo_service, system_server_service, service_manager_type;
五、如何裁剪系统服务
所谓的系统服务裁剪,就是不让服务启动且其它获取该服务的地方有判空,避免运行时空指针报错。以printmanagerservice服务为例:
// packagemanager
public static final String FEATURE_PRINTING = "android.software.print";private void startOtherServices(@NonNull TimingsTraceAndSlog t) {// 这类系统服务可以做裁剪,只需让hasSystemFeature方法返回false if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_PRINTING)) {t.traceBegin("StartPrintManager");mSystemServiceManager.startService(PRINT_MANAGER_SERVICE_CLASS);t.traceEnd();}}...
}
hasSystemFeature实现:
// 通过mAvailableFeatures得到所有的feature
public boolean hasSystemFeature(String name, int version) {// allow instant applicationssynchronized (mAvailableFeatures) {final FeatureInfo feat = mAvailableFeatures.get(name);if (feat == null) {return false;} else {return feat.version >= version;}}
}// 该方法维护mAvailableFeatures列表
private void addFeature(String name, int version) {FeatureInfo fi = mAvailableFeatures.get(name);if (fi == null) {fi = new FeatureInfo();fi.name = name;fi.version = version;mAvailableFeatures.put(name, fi);} else {fi.version = Math.max(fi.version, version);}
}
// 系统启动时会去读取handheld_core_hardware.xml配置文件,存到mAvailableFeatures列表
SystemConfig() {TimingsTraceLog log = new TimingsTraceLog(TAG, Trace.TRACE_TAG_SYSTEM_SERVER);log.traceBegin("readAllPermissions");try {readAllPermissions();readPublicNativeLibrariesList();} finally {log.traceEnd();}
}// 读取handheld_core_hardware.xml配置文件
private void readPermissionsFromXml(final XmlPullParser parser, File permFile,int permissionFlag) {...case "feature": {if (allowFeatures) {String fname = parser.getAttributeValue(null, "name");int fversion = XmlUtils.readIntAttribute(parser, "version", 0);boolean allowed;if (!lowRam) {allowed = true;} else {String notLowRam = parser.getAttributeValue(null, "notLowRam");allowed = !"true".equals(notLowRam);}if (fname == null) {Slog.w(TAG, "<" + name + "> without name in " + permFile + " at "+ parser.getPositionDescription());} else if (allowed) {addFeature(fname, fversion);}} else {logNotAllowedInPartition(name, permFile, parser);}XmlUtils.skipCurrentTag(parser);} break;...
}
只要注释掉<feature name="android.software.print" />,hasSystemFeature方法返回false,printmanagerservice服务就不会启动,如下:
// frameworks/native/data/etc/handheld_core_hardware.xml<!-- basic system services --><feature name="android.software.app_widgets" /><feature name="android.software.telecom" /><feature name="android.software.voice_recognizers" notLowRam="true" /><feature name="android.software.backup" /><feature name="android.software.home_screen" /><feature name="android.software.input_methods" /><feature name="android.software.picture_in_picture" notLowRam="true" /><feature name="android.software.activities_on_secondary_displays" notLowRam="true" />// <feature name="android.software.print" /><feature name="android.software.companion_device_setup" /><feature name="android.software.autofill" /><feature name="android.software.credentials" /><feature name="android.software.cant_save_state" /><feature name="android.software.secure_lock_screen" /><feature name="android.software.window_magnification" />...
</permissions>
PRODUCT_COPY_FILES := \ frameworks/native/data/etc/handheld_core_hardware.xml:system/etc/permissions/handheld_core_hardware.xml
app进程或系统其它服务在使用该服务前会做空判断,避免服务获取不到引入的空指针错误:
// 服务注册
registerService(Context.PRINT_SERVICE, PrintManager.class,new CachedServiceFetcher<PrintManager>() {@Overridepublic PrintManager createService(ContextImpl ctx) throws ServiceNotFoundException {IPrintManager service = null;// If the feature not present, don't try to look up every timeif (ctx.getPackageManager().hasSystemFeature(PackageManager.FEATURE_PRINTING)) {service = IPrintManager.Stub.asInterface(ServiceManager.getServiceOrThrow(Context.PRINT_SERVICE));}final int userId = ctx.getUserId();final int appId = UserHandle.getAppId(ctx.getApplicationInfo().uid);return new PrintManager(ctx.getOuterContext(), service, userId, appId);
}});public PrintManager(Context context, IPrintManager service, int userId, int appId) {mContext = context;mService = service;...
}// app进程调用服务相关接口之前会做null判断,避免服务获取失败导致空指针错误
public PrintJob getPrintJob(PrintJobId printJobId) {if (mService == null) {Log.w(LOG_TAG, "Feature android.software.print not available");return null;}try {PrintJobInfo printJob = mService.getPrintJobInfo(printJobId, mAppId, mUserId);if (printJob != null) {return new PrintJob(printJob, this);}} catch (RemoteException re) {throw re.rethrowFromSystemServer();}return null;
}// 其它服务在调用该服务之前会做hasSystemFeature判断是否可用
@Override
public int getAvailabilityStatus() {return mPackageManager.hasSystemFeature(PackageManager.FEATURE_PRINTING)&& mPrintManager != null? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
六、其它模块
6.1 NativeCrashListener
NativeCrashListener线程模块用于监听native crash事件,即当某个进程发生native crash时,由crash_dump64进程通过socket(ndebugsocket)方式将crash debug信息传给NativeCrashListener模块,并传给AMS服务写入dropbox.
-
流程框架
system_server进程启动的systemReady阶段创建NativeCrashListener线程,该线程创建"ndebugsocket" socket服务端,当有进程发生native crash时,crash_dump64客户端进程通过socket与system_server通信,最后将数据存到"data/system/dropbox"目录。
-
核心代码段
// frameworks/base/services/java/com/android/server/SystemServer.javamActivityManagerService.systemReady(() -> {...mSystemServiceManager.startBootPhase(t, SystemService.PHASE_ACTIVITY_MANAGER_READY);...mActivityManagerService.startObservingNativeCrashes();...
}
// rameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public void startObservingNativeCrashes() {final NativeCrashListener ncl = new NativeCrashListener(this);ncl.start();
}
// frameworks/base/services/core/java/com/android/server/am/NativeCrashListener.javafinal class NativeCrashListener extends Thread {static final String DEBUGGERD_SOCKET_PATH = "/data/system/ndebugsocket";static final long SOCKET_TIMEOUT_MILLIS = 10000; final ActivityManagerService mAm;// 内部类线程class NativeCrashReporter extends Thread {ProcessRecord mApp;int mSignal;boolean mGwpAsanRecoverableCrash;String mCrashReport;NativeCrashReporter(ProcessRecord app, int signal, boolean gwpAsanRecoverableCrash,String report) {super("NativeCrashReport");mApp = app;mSignal = signal;mGwpAsanRecoverableCrash = gwpAsanRecoverableCrash;mCrashReport = report;}@Overridepublic void run() {try {CrashInfo ci = new CrashInfo();ci.exceptionClassName = "Native crash";ci.exceptionMessage = Os.strsignal(mSignal);ci.throwFileName = "unknown";ci.throwClassName = "unknown";ci.throwMethodName = "unknown";ci.stackTrace = mCrashReport;// crash数据传给AMS,由AMS写入dropboxmAm.handleApplicationCrashInner(mGwpAsanRecoverableCrash ? "native_recoverable_crash" : "native_crash",mApp, mApp.processName, ci);if (DEBUG) Slog.v(TAG, "<-- handleApplicationCrash() returned");} catch (Exception e) {Slog.e(TAG, "Unable to report native crash", e);}}}// 在system_server进程启动的systemReady阶段执行,创建socke server,进入循环监听@Overridepublic void run() {final byte[] ackSignal = new byte[1];{File socketFile = new File(DEBUGGERD_SOCKET_PATH);if (socketFile.exists()) {socketFile.delete();}}try {FileDescriptor serverFd = Os.socket(AF_UNIX, SOCK_STREAM, 0);final UnixSocketAddress sockAddr = UnixSocketAddress.createFileSystem(DEBUGGERD_SOCKET_PATH);Os.bind(serverFd, sockAddr);Os.listen(serverFd, 1);Os.chmod(DEBUGGERD_SOCKET_PATH, 0777);while (true) {FileDescriptor peerFd = null;try {if (MORE_DEBUG) Slog.v(TAG, "Waiting for debuggerd connection");peerFd = Os.accept(serverFd, null /* peerAddress */);if (MORE_DEBUG) Slog.v(TAG, "Got debuggerd socket " + peerFd);if (peerFd != null) {// 数据客户端的信息consumeNativeCrashData(peerFd);}} catch (Exception e) {Slog.w(TAG, "Error handling connection", e);} finally {...}}// 读取client socket数据,存到byte[] bufferstatic int readExactly(FileDescriptor fd, byte[] buffer, int offset, int numBytes)throws ErrnoException, InterruptedIOException {int totalRead = 0;while (numBytes > 0) {int n = Os.read(fd, buffer, offset + totalRead, numBytes);if (n <= 0) {if (DEBUG) {Slog.w(TAG, "Needed " + numBytes + " but saw " + n);}return -1; // premature EOF or timeout}numBytes -= n;totalRead += n;}return totalRead;}// Read a crash report from the connectionvoid consumeNativeCrashData(FileDescriptor fd) {final byte[] buf = new byte[4096];final ByteArrayOutputStream os = new ByteArrayOutputStream(4096);try {StructTimeval timeout = StructTimeval.fromMillis(SOCKET_TIMEOUT_MILLIS);Os.setsockoptTimeval(fd, SOL_SOCKET, SO_RCVTIMEO, timeout);Os.setsockoptTimeval(fd, SOL_SOCKET, SO_SNDTIMEO, timeout);int headerBytes = readExactly(fd, buf, 0, 9);boolean gwpAsanRecoverableCrash = buf[8] != 0;...// byte[]转Stringint bytes;do {// get some databytes = Os.read(fd, buf, 0, buf.length);if (bytes > 0) {if (MORE_DEBUG) {String s = new String(buf, 0, bytes, "UTF-8");Slog.v(TAG, "READ=" + bytes + "> " + s);}// did we just get the EOD null byte?if (buf[bytes - 1] == 0) {os.write(buf, 0, bytes - 1); // exclude the EOD tokenbreak;}// no EOD, so collect it and read moreos.write(buf, 0, bytes);}} while (bytes > 0);if (!gwpAsanRecoverableCrash) {synchronized (mAm) {synchronized (mAm.mProcLock) {pr.mErrorState.setCrashing(true);pr.mErrorState.setForceCrashReport(true);}}}final String reportString = new String(os.toByteArray(), "UTF-8");(new NativeCrashReporter(pr, signal, gwpAsanRecoverableCrash, reportString)).start();} catch (Exception e) {Slog.e(TAG, "Exception dealing with report", e);// ugh, fail.}}}
6.2 Android watchdog
Android watchdog用于监测系统服务、UI线程、动画线程等是否出现死锁或卡死,system_server进程启动时会启动watchdog线程,进入监听,系统服务启动时会加入watchdog监听。
private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {......// Start the watchdog as early as possible so we can crash the system server// if we deadlock during early boott.traceBegin("StartWatchdog");final Watchdog watchdog = Watchdog.getInstance(); // 对象创建watchdog.start(); // 启动watchdong线程mDumper.addDumpable(watchdog);......
}
-
实现原理
以PMS服务为例,
1)PMS服务实现Watchdog.Monitor接口,服务启动时,将PMS服务对象加入到watchdong的Monitor列表
2)system_server进程启动时,会启动watchdog线程,每隔30s会启动monitor线程调用monitor列表中的PMS对象加锁的monitor方法,如果超过30s没有返回,说明一直在等待锁,即PMS服务卡死。
// PowerManagerService.java
public final class PowerManagerService extends SystemServiceimplements Watchdog.Monitor {...@Overridepublic void onStart() {// 加入watchdog监听Watchdog.getInstance().addMonitor(this); // pms服务实现了Watchdog.Monitor接口...}// 在watch dog中调用,超过30s没有返回,说明一直在等待锁,即服务卡死@Override public void monitor() {// Grab and release lock for watchdog monitor to detect deadlocks.synchronized (mLock) {}}...
}// frameworks/base/services/core/java/com/android/server/Watchdog.java
public class Watchdog implements Dumpable {...private final Thread mThread;private final HandlerChecker mMonitorChecker;private Watchdog() {// 创建watchdog线程mThread = new Thread(this::run, "watchdog");// 创建monitor线程mMonitorChecker = new HandlerChecker(new Handler(t.getLooper()), "monitor thread");...}public void start() {// 启动watchdog线程,执行Watchdog类中的run方法mThread.start();}public void addMonitor(Monitor monitor) {synchronized (mLock) {mMonitorChecker.addMonitorLocked(monitor);}}private void run() {boolean waitedHalf = false;while (true) {List<HandlerChecker> blockedCheckers = Collections.emptyList();String subject = "";boolean allowRestart = true;int debuggerWasConnected = 0;boolean doWaitedHalfDump = false;final long watchdogTimeoutMillis = mWatchdogTimeoutMillis;final long checkIntervalMillis = watchdogTimeoutMillis / 2;final ArrayList<Integer> pids;synchronized (mLock) {long timeout = checkIntervalMillis;for (int i=0; i<mHandlerCheckers.size(); i++) {HandlerCheckerAndTimeout hc = mHandlerCheckers.get(i);// 执行内部类HandlerChecker中的scheduleCheckLocked方法hc.checker().scheduleCheckLocked(hc.customTimeoutMillis().orElse(watchdogTimeoutMillis * Build.HW_TIMEOUT_MULTIPLIER));}...} public final class HandlerChecker implements Runnable {...private Monitor mCurrentMonitor;private final ArrayList<Monitor> mMonitors = new ArrayList<Monitor>();private final ArrayList<Monitor> mMonitorQueue = new ArrayList<Monitor>();HandlerChecker(Handler handler, String name) {mHandler = handler;mName = name;mCompleted = true;}void addMonitorLocked(Monitor monitor) {mMonitorQueue.add(monitor);}public void scheduleCheckLocked(long handlerCheckerTimeoutMillis) {mWaitMaxMillis = handlerCheckerTimeoutMillis;if (mCompleted) {// Safe to update monitors in queue, Handler is not in the middle of workmMonitors.addAll(mMonitorQueue);mMonitorQueue.clear();}if ((mMonitors.size() == 0 && mHandler.getLooper().getQueue().isPolling())|| (mPauseCount > 0)) {mCompleted = true;return;}if (!mCompleted) {// we already have a check in flight, so no needreturn;}mCompleted = false;mCurrentMonitor = null;mStartTimeMillis = SystemClock.uptimeMillis();// 发送消息,插入消息队列最开头,执行下面的run()方法mHandler.postAtFrontOfQueue(this);}@Overridepublic void run() {final int size = mMonitors.size();for (int i = 0 ; i < size ; i++) {synchronized (mLock) {mCurrentMonitor = mMonitors.get(i);}// 开始监测服务是否出现死锁或卡死mCurrentMonitor.monitor();}synchronized (mLock) {mCompleted = true;mCurrentMonitor = null;}}...} // HandlerChecker内部类...
} // Watchdog
相关文章:

Android system_server进程
目录 一、system_server进程介绍 二、system_server进程启动流程 2.1 startBootstrapServices 2.2 startCoreServices 2.3 startOtherServices 2.4 startApexServices 三、如何使用系统服务 3.1 app进程调用系统服务 3.2 native进程调用系统服务 3.3 system_server进…...

Vue3+element-plus 实现中英文切换(Vue-i18n组件的使用)
1、前言 在 Vue 3 项目中结合 vue-i18n 和 Element Plus 实现中英文切换是一个常见的需求。下面是一个详细的步骤指南,帮助你完成这个任务。 安装引入 1. 安装依赖 首先,你需要安装 vue-i18n 和 Element Plus。 npm install vue-i18nnext element-p…...

python实现猜数字游戏( 可视化easygui窗口版本 )
1.先上源代码 import random import easygui as egdef guess_ordinary():answer random.randint(0, 11)user_answer int(eg.enterbox(msg "请在0-10中选择一个整数: ", title "猜数字"))if user_answer answer:eg.msgbox(msg "恭喜你ÿ…...

自由学习记录(23)
Lua的学习 table.concat(tb,";") 如果表里带表,则不能拼接,表里带nil也不能,都会报错 true和false也不可以,数字和字符串可以 if要和一个end配对,所以 if a>b then return true end end 两个end …...

Java语言程序设计 选填题知识点总结
第一章 javac.exe是JDK提供的编译器public static void main (String args[])是Java应用程序主类中正确的main方法Java源文件是由若干个书写形式互相独立的类组成的Java语言的名字是印度尼西亚一个盛产咖啡的岛名Java源文件中可以有一个或多个类Java源文件的扩展名是.java如果…...

鸿蒙生态:开发者的新蓝海与挑战
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,…...

4.3 MySQL 存储函数
存储函数是一种数据库对象,允许用户将常用的 SQL 逻辑封装为可复用的函数,通过调用函数完成特定的计算或业务逻辑。 1. 简介 1.1 什么是存储函数 存储函数(Stored Function)是用户定义的一段 SQL 逻辑,返回一个值&am…...

【Python刷题】动态规划相关问题
动态规划(Dynamic Programming,简称 DP)是一种用于解决多阶段决策最优化问题的算法策略。它通过把原问题分解为相对简单的子问题,记录子问题的解(通常使用表格等数据结构存储),避免重复计算&…...

2024年9月中国电子学会青少年软件编程(Python)等级考试试卷(六级)答案 + 解析
一、单选题 1、下面代码运行后出现的图像是?( ) import matplotlib.pyplot as plt import numpy as np x np.array([A, B, C, D]) y np.array([30, 25, 15, 35]) plt.bar(x, y) plt.show() A. B. C. D. 正确答案:A 答案…...

论文阅读:SIMBA: single-cell embedding along with features
Chen, H., Ryu, J., Vinyard, M.E. et al. SIMBA: single-cell embedding along with features. Nat Methods 21, 1003–1013 (2024). 论文地址:https://doi.org/10.1038/s41592-023-01899-8 代码地址:https://github.com/pinellolab/simba. 摘要 大多…...

d3-quadtree 的属性、方法、示例
D3.js 的 d3-quadtree 模块提供了用于构建二维空间索引的数据结构,即四叉树(Quadtree)。四叉树可以高效地存储和查询大量点数据。下面列出了 d3-quadtree 的主要属性和方法,并提供了一个简单的 Vue 组件示例,展示如何使…...

初次体验加猜测信息安全管理与评估国赛阶段训练习
[第一部分] 网络安全事件响应 window操作系统服务器应急响应流程_windows 服务器应急响应靶场_云无迹的博客-CSDN博客 0、请提交攻击者攻击成功的第一时间,格式:YY:MM:DD hh:mm:ss1、请提交攻击者的浏览器版本2、请提交攻击者目录扫描所使用的工具名称…...

在WSUS中删除更新
WSUS中更新的管理逻辑 如果你探索过WSUS控制台界面,就会发现WSUS只给你提供了批准(Approve)和拒绝(Decline)更新的选项,并无办法删除更新。 如果你去WSUS服务器清理导向(WSUS Server Cleanup …...

5分钟轻松搭建Immich图片管理软件并实现公网远程传输照片
文章目录 前言1.关于Immich2.安装Docker3.本地部署Immich4.Immich体验5.安装cpolar内网穿透6.创建远程链接公网地址7.使用固定公网地址远程访问 前言 本篇文章介绍如何在本地搭建lmmich图片管理软件,并结合cpolar内网穿透实现公网远程访问到局域网内的lmmich&#…...

数据集-目标检测系列- 昙花(昙花一现) 检测数据集 epiphyllum >> DataBall
数据集-目标检测系列- 昙花(昙花一现) 检测数据集 epiphyllum >> DataBall DataBall 助力快速掌握数据集的信息和使用方式,会员享有 百种数据集,持续增加中。 贵在坚持! 数据样例项目地址: * 相关…...

开源POC库推荐
声明 学习视频来自 B 站UP主泷羽sec,如涉及侵权马上删除文章。 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负。 ✍🏻作者简介:致…...

vue3项目部署在阿里云轻量应用服务器上
文章目录 概要整体部署流程技术细节小结 概要 vue3前端项目部署在阿里云轻量服务器 整体部署流程 首先有一个Vue3前端项目和阿里云应用服务器 确保环境准备 如果是新的服务器,在服务器内运行以下命令更新软件包 sudo apt update && sudo apt upgrade -y …...

javascrip页面交互
元素的三大系列 offset系列 offset初相识 offset系列属性 作用 element.offsetParent 返回作为该元素带有定位的父级元素,如果父级没有定位,则返回body element.offsetTop 返回元素相对于有定位父元素上方的偏移量 element.offsetLeft 返回元素…...

【U盘车载音乐】某宝198的3068首车载专用音乐合集【高音质】24G
「【U盘车载音乐】某宝198的3068首车载专用音乐合集【高音质】24G」 复制下方口令,打开最新版「夸克APP」即可获取保存(防止和谐!!!) 口令: 动作懿范鉴真渡多好备用口令: /~19dc35…...
【论文阅读】WGSR
0. 摘要 0.1. 问题提出 1.超分辨率(SR)是一个不适定逆问题,可行解众多。 2.超分辨率(SR)算法在可行解中寻找一个在保真度和感知质量之间取得平衡的“良好”解。 3.现有的方法重建高频细节时会产生伪影和幻觉,模型区分图像细节与伪影仍是难题。 0.2. …...

打造智能化在线教育平台详解:教培网校APP的架构设计与实现
本篇文章,小编将以教培网校APP的架构设计与实现为核心,深入探讨如何打造一套智能化的在线教育平台,为企业和教育机构提供落地参考。 一、在线教育平台的核心功能需求 构建一个高效的教培网校APP,首先需要明确其核心功能需求。一…...

使用同一个链接,如何实现PC打开是web应用,手机打开是一个H5应用
当我们希望通过同一个 URL,根据访问设备展示不同的页面时,可以选择以下几种方法: 方法一:通过 User-Agent 前端判断设备类型并跳转 利用前端 JavaScript 获取浏览器的 User-Agent 字符串,判断设备类型,跳转…...

STM32-- 调试 -日志输出
在调试嵌入式程序时,输出日志是非常重要的环节,可以帮助开发者定位问题、监控程序状态和性能。以下是几种常见的日志输出方式及其适用场景: 1. 使用串口(UART)输出日志 实现方式: 通过串口将日志输出到主…...

Python爬虫案例八:抓取597招聘网信息并用xlutils进行excel数据的保存
excel保存数据的三种方式: 1、pandas保存excel数据,后缀名为xlsx; 举例: import pandas as pddic {姓名: [张三, 李四, 王五, 赵六],年龄: [18, 19, 20, 21],住址: [广州, 青岛, 南京, 重庆] } dic_file pd.DataFrame(dic) dic_file…...

小试牛刀-Anchor安装和基础测试
目录 一、编写目的 二、安装步骤 2.1 安装Rust 设置rustup镜像 安装Rust 2.2 安装node.js 2.3 安装Solana-CLI 2.4 安装Anchor CLI 三、Program测试 四、可能出现的问题 Welcome to Code Blocks blog 本篇文章主要介绍了 [Anchor安装和基础测试] 博主广交技术好友&…...

51单片机基础01 单片机最小系统
目录 一、什么是51单片机 二、51单片机的引脚介绍 1、VCC GND 2、XTAL1 2 3、RST 4、EA 5、PSEN 6、ALE 7、RXD、TXD 8、INT0、INT1 9、T0、T1 10、MOSI、MISO、SCK 11、WR、RD 12、通用IO P0 13、通用IO P1 14、通用IO P2 三、51单片机的最小系统 1、供电与…...

RocketMQ文件刷盘机制深度解析与Java模拟实现
引言 在现代分布式系统中,消息队列(Message Queue, MQ)作为一种重要的中间件,扮演着连接不同服务、实现异步通信和消息解耦的关键角色。Apache RocketMQ作为一款高性能的分布式消息中间件,广泛应用于实时数据流处理、…...

python语言基础-5 进阶语法-5.3 流式编程
声明:本内容非盈利性质,也不支持任何组织或个人将其用作盈利用途。本内容来源于参考书或网站,会尽量附上原文链接,并鼓励大家看原文。侵删。 5.3 流式编程(参考链接:https://www.zhihu.com/question/59062…...

JVM性能分析工具JProfiler的使用
一、基本概念 JProfiler:即“Java Profiler”,即“Java分析器”或“Java性能分析工具”。它是一款用于Java应用程序的性能分析和调试工具,主要帮助开发人员识别和解决性能瓶颈问题。 JVM:即“Java Virtual Machine”,…...

面试题: Spring中的事务是如何实现的?
Spring中的事务是如何实现的? 背景个人原因的背景正规一点的背景 答案一些思绪和灵感个人理解程度拓展知识Spring的事务管理主要涉及哪几个类?在Spring中,事务管理的流程是怎样的? 背景 个人原因的背景 想换工作, 刷面试题看到的问题, 简单记录一下, 算是个人…...