public static void main(String argv[]) {
    try {
      // Start profiling the zygote initialization.
      SamplingProfilerIntegration.start();

      registerZygoteSocket();
      EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, SystemClock.uptimeMillis());
      preloadClasses();
      // cacheRegisterMaps();
      preloadResources();
      EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, SystemClock.uptimeMillis());

      if (SamplingProfilerIntegration.isEnabled()) {
        SamplingProfiler sp = SamplingProfiler.getInstance();
        sp.pause();
        SamplingProfilerIntegration.writeZygoteSnapshot();
        sp.shutDown();
      }

      // Do an initial gc to clean up after startup
      gc();

      // If requested, start system server directly from Zygote
      if (argv.length != 2) {
        throw new RuntimeException(argv[0] + USAGE_STRING);
      }

      if (argv[1].equals("true")) {
        startSystemServer();
      } else if (!argv[1].equals("false")) {
        throw new RuntimeException(argv[0] + USAGE_STRING);
      }

      Log.i(TAG, "Accepting command socket connections");

      if (ZYGOTE_FORK_MODE) {
        runForkMode();
      } else {
        runSelectLoopMode();
      }

      closeServerSocket();
    } catch (MethodAndArgsCaller caller) {
      caller.run();
    } catch (RuntimeException ex) {
      Log.e(TAG, "Zygote died with exception", ex);
      closeServerSocket();
      throw ex;
    }
  }
  public static void main(String argv[]) {
    CheckPoint cp = new CheckPoint();
    try {
      // Start profiling the zygote initialization.
      SamplingProfilerIntegration.start();

      EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, SystemClock.uptimeMillis());
      preload();
      cp.checkPoint("/data/zygote.ss");
      EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, SystemClock.uptimeMillis());
      registerZygoteSocket();

      // Finish profiling the zygote initialization.
      SamplingProfilerIntegration.writeZygoteSnapshot();

      // Do an initial gc to clean up after startup
      gc();

      // If requested, start system server directly from Zygote
      if (argv.length != 2) {
        throw new RuntimeException(argv[0] + USAGE_STRING);
      }

      if (argv[1].equals("start-system-server")) {
        startSystemServer();
      } else if (!argv[1].equals("")) {
        throw new RuntimeException(argv[0] + USAGE_STRING);
      }

      Log.i(TAG, "Accepting command socket connections");

      if (ZYGOTE_FORK_MODE) {
        runForkMode();
      } else {
        runSelectLoopMode();
      }

      closeServerSocket();
    } catch (MethodAndArgsCaller caller) {
      caller.run();
    } catch (RuntimeException ex) {
      Log.e(TAG, "Zygote died with exception", ex);
      closeServerSocket();
      throw ex;
    }
  }
  public static void main(String argv[]) {
    try {
      Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygoteInit");
      RuntimeInit.enableDdms();
      // Start profiling the zygote initialization.
      SamplingProfilerIntegration.start();

      boolean startSystemServer = false;
      String socketName = "zygote";
      String abiList = null;
      for (int i = 1; i < argv.length; i++) {
        if ("start-system-server".equals(argv[i])) {
          startSystemServer = true;
        } else if (argv[i].startsWith(ABI_LIST_ARG)) {
          abiList = argv[i].substring(ABI_LIST_ARG.length());
        } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
          socketName = argv[i].substring(SOCKET_NAME_ARG.length());
        } else {
          throw new RuntimeException("Unknown command line argument: " + argv[i]);
        }
      }

      if (abiList == null) {
        throw new RuntimeException("No ABI list supplied.");
      }

      registerZygoteSocket(socketName);
      Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygotePreload");
      EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, SystemClock.uptimeMillis());
      preload();
      EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, SystemClock.uptimeMillis());
      Trace.traceEnd(Trace.TRACE_TAG_DALVIK);

      // Finish profiling the zygote initialization.
      SamplingProfilerIntegration.writeZygoteSnapshot();

      // Do an initial gc to clean up after startup
      Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PostZygoteInitGC");
      gcAndFinalize();
      Trace.traceEnd(Trace.TRACE_TAG_DALVIK);

      Trace.traceEnd(Trace.TRACE_TAG_DALVIK);

      // Disable tracing so that forked processes do not inherit stale tracing tags from
      // Zygote.
      Trace.setTracingEnabled(false);

      if (startSystemServer) {
        startSystemServer(abiList, socketName);
      }

      Log.i(TAG, "Accepting command socket connections");
      runSelectLoop(abiList);

      closeServerSocket();
    } catch (MethodAndArgsCaller caller) {
      caller.run();
    } catch (RuntimeException ex) {
      Log.e(TAG, "Zygote died with exception", ex);
      closeServerSocket();
      throw ex;
    }
  }
  private void run() {
    // If a device's clock is before 1970 (before 0), a lot of
    // APIs crash dealing with negative numbers, notably
    // java.io.File#setLastModified, so instead we fake it and
    // hope that time from cell towers or NTP fixes it shortly.
    if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
      Slog.w(TAG, "System clock is before 1970; setting to 1970.");
      SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
    }

    // Here we go!
    Slog.i(TAG, "Entered the Android system server!");
    EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());

    // In case the runtime switched since last boot (such as when
    // the old runtime was removed in an OTA), set the system
    // property so that it is in sync. We can't do this in
    // libnativehelper's JniInvocation::Init code where we already
    // had to fallback to a different runtime because it is
    // running as root and we need to be the system user to set
    // the property. http://b/11463182
    SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());

    // Enable the sampling profiler.
    if (SamplingProfilerIntegration.isEnabled()) {
      SamplingProfilerIntegration.start();
      mProfilerSnapshotTimer = new Timer();
      mProfilerSnapshotTimer.schedule(
          new TimerTask() {
            @Override
            public void run() {
              SamplingProfilerIntegration.writeSnapshot("system_server", null);
            }
          },
          SNAPSHOT_INTERVAL,
          SNAPSHOT_INTERVAL);
    }

    // Mmmmmm... more memory!
    VMRuntime.getRuntime().clearGrowthLimit();

    // The system server has to run all of the time, so it needs to be
    // as efficient as possible with its memory usage.
    VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);

    // Some devices rely on runtime fingerprint generation, so make sure
    // we've defined it before booting further.
    Build.ensureFingerprintProperty();

    // Within the system server, it is an error to access Environment paths without
    // explicitly specifying a user.
    Environment.setUserRequired(true);

    // Ensure binder calls into the system always run at foreground priority.
    BinderInternal.disableBackgroundScheduling(true);

    // Prepare the main looper thread (this thread).
    android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);
    android.os.Process.setCanSelfBackground(false);
    Looper.prepareMainLooper();

    // Initialize native services.
    System.loadLibrary("android_servers");

    // Check whether we failed to shut down last time we tried.
    // This call may not return.
    performPendingShutdown();

    // Initialize the system context.
    createSystemContext();

    // Create the system service manager.
    mSystemServiceManager = new SystemServiceManager(mSystemContext);
    LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

    // Start services.
    try {
      startBootstrapServices();
      startCoreServices();
      startOtherServices();
    } catch (Throwable ex) {
      Slog.e("System", "******************************************");
      Slog.e("System", "************ Failure starting system services", ex);
      throw ex;
    }

    // For debug builds, log event loop stalls to dropbox for analysis.
    if (StrictMode.conditionallyEnableDebugLogging()) {
      Slog.i(TAG, "Enabled StrictMode for system server main thread.");
    }

    // Loop forever.
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
  }