diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 6b45ba2ae8aa8..5b9460a226bb9 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -1052,6 +1052,17 @@ public final class SystemServer implements Dumpable { private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) { t.traceBegin("startBootstrapServices"); + t.traceBegin("ArtModuleServiceInitializer"); + // This needs to happen before DexUseManagerLocal init. We do it here to avoid colliding + // with a GC. ArtModuleServiceInitializer is a class from a separate dex file + // "service-art.jar", so referencing it involves the class linker. The class linker and the + // GC are mutually exclusive (b/263486535). Therefore, we do this here to force trigger the + // class linker earlier. If we did this later, especially after PackageManagerService init, + // the class linker would be consistently blocked by a GC because PackageManagerService + // allocates a lot of memory and almost certainly triggers a GC. + ArtModuleServiceInitializer.setArtModuleServiceManager(new ArtModuleServiceManager()); + t.traceEnd(); + // Start the watchdog as early as possible so we can crash the system server // if we deadlock during early boot t.traceBegin("StartWatchdog"); @@ -1238,8 +1249,6 @@ public final class SystemServer implements Dumpable { t.traceBegin("DexUseManagerLocal"); // DexUseManagerLocal needs to be loaded after PackageManagerLocal has been registered, but // before PackageManagerService starts processing binder calls to notifyDexLoad. - // DexUseManagerLocal may also call artd, so ensure ArtModuleServiceManager is instantiated. - ArtModuleServiceInitializer.setArtModuleServiceManager(new ArtModuleServiceManager()); LocalManagerRegistry.addManager( DexUseManagerLocal.class, DexUseManagerLocal.createInstance()); t.traceEnd();