diff --git a/core/authorize.php b/core/authorize.php
index f938f39..c98de17 100644
--- a/core/authorize.php
+++ b/core/authorize.php
@@ -47,7 +47,8 @@
  *   TRUE if the current user can run authorize.php, and FALSE if not.
  */
 function authorize_access_allowed() {
-  \Drupal::service('session_manager')->initialize();
+  // Initialize the session manager.
+  \Drupal::service('session_manager');
   return Settings::get('allow_authorize_operations', TRUE) && user_access('administer software updates');
 }
 
diff --git a/core/core.services.yml b/core/core.services.yml
index 5b410a2..eb3a628 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -779,8 +779,8 @@ services:
   session_manager:
     class: Drupal\Core\Session\SessionManager
     arguments: ['@request_stack', '@database', '@session_manager.metadata_bag', '@settings']
-    tags:
-      - { name: persist }
+    calls:
+      - [initialize]
   session_manager.metadata_bag:
     class: Drupal\Core\Session\MetadataBag
     arguments: ['@settings']
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index b00d23b..b6cc1a5 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -1456,7 +1456,8 @@ function install_load_profile(&$install_state) {
  */
 function install_bootstrap_full() {
   drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
-  \Drupal::service('session_manager')->initialize();
+  // Initialize the session manager.
+  \Drupal::service('session_manager');
 }
 
 /**
diff --git a/core/lib/Drupal/Core/Authentication/Provider/Cookie.php b/core/lib/Drupal/Core/Authentication/Provider/Cookie.php
index 167a0b0..d33a59b 100644
--- a/core/lib/Drupal/Core/Authentication/Provider/Cookie.php
+++ b/core/lib/Drupal/Core/Authentication/Provider/Cookie.php
@@ -47,7 +47,7 @@ public function applies(Request $request) {
   public function authenticate(Request $request) {
     // Global $user is deprecated, but the session system is still based on it.
     global $user;
-    if ($this->sessionManager->initialize()->isStarted()) {
+    if ($this->sessionManager->isStarted()) {
       return $user;
     }
     return NULL;
diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php
index 2b788dc..5c8b0c6 100644
--- a/core/lib/Drupal/Core/DrupalKernel.php
+++ b/core/lib/Drupal/Core/DrupalKernel.php
@@ -402,6 +402,7 @@ protected function initializeContainer() {
     // The request service requires custom persisting logic, since it is also
     // potentially scoped.
     $request_scope = FALSE;
+    $has_session_manager = FALSE;
     if (isset($this->container)) {
       if ($this->container->isScopeActive('request')) {
         $request_scope = TRUE;
@@ -409,6 +410,11 @@ protected function initializeContainer() {
       if ($this->container->initialized('request')) {
         $request = $this->container->get('request');
       }
+      // If there is a session manager, close and save the session.
+      $has_session_manager = $this->container->initialized('session_manager');
+      if ($has_session_manager) {
+        $this->container->get('session_manager')->save();
+      }
     }
     $this->container = NULL;
     $class = $this->getClassName();
@@ -466,6 +472,9 @@ protected function initializeContainer() {
     if (isset($request)) {
       $this->container->set('request', $request);
     }
+    if ($has_session_manager) {
+      $this->container->get('session_manager');
+    }
     \Drupal::setContainer($this->container);
   }
 
diff --git a/core/lib/Drupal/Core/Session/SessionManager.php b/core/lib/Drupal/Core/Session/SessionManager.php
index f656b2d..4414a89 100644
--- a/core/lib/Drupal/Core/Session/SessionManager.php
+++ b/core/lib/Drupal/Core/Session/SessionManager.php
@@ -89,10 +89,18 @@ class SessionManager extends NativeSessionStorage implements SessionManagerInter
    *   The settings instance.
    */
   public function __construct(RequestStack $request_stack, Connection $connection, SymfonyMetadataBag $metadata_bag, Settings $settings) {
-    parent::__construct();
+    $options = array();
+
     $this->requestStack = $request_stack;
     $this->connection = $connection;
-    $this->setMetadataBag($metadata_bag);
+
+    // Register the default session handler.
+    // @todo Extract session storage from session handler into a service.
+    $save_handler = new SessionHandler($this, $this->requestStack, $this->connection);
+    $write_check_handler = new WriteCheckSessionHandler($save_handler);
+    $this->setSaveHandler($write_check_handler);
+
+    parent::__construct($options, $write_check_handler, $metadata_bag);
 
     $this->setMixedMode($settings->get('mixed_mode_sessions', FALSE));
 
@@ -111,12 +119,6 @@ public function __construct(RequestStack $request_stack, Connection $connection,
   public function initialize() {
     global $user;
 
-    // Register the default session handler.
-    // @todo Extract session storage from session handler into a service.
-    $save_handler = new SessionHandler($this, $this->requestStack, $this->connection);
-    $write_check_handler = new WriteCheckSessionHandler($save_handler);
-    $this->setSaveHandler($write_check_handler);
-
     $is_https = $this->requestStack->getCurrentRequest()->isSecure();
     $cookies = $this->requestStack->getCurrentRequest()->cookies;
     $insecure_session_name = $this->getInsecureName();
@@ -174,7 +176,7 @@ public function start() {
   public function save() {
     global $user;
 
-    if (!$this->isEnabled()) {
+    if (!$this->isEnabled() || $this->isCli()) {
       // We don't have anything to do if we are not allowed to save the session.
       return;
     }
@@ -189,7 +191,7 @@ public function save() {
     else {
       // There is session data to store. Start the session if it is not already
       // started.
-      if (!$this->isStarted()) {
+      if (!$this->getSaveHandler()->isActive()) {
         $this->start();
         if ($this->requestStack->getCurrentRequest()->isSecure() && $this->isMixedMode()) {
           $insecure_session_name = $this->getInsecureName();
@@ -211,7 +213,7 @@ public function regenerate($destroy = FALSE, $lifetime = NULL) {
     global $user;
 
     // Nothing to do if we are not allowed to change the session.
-    if (!$this->isEnabled()) {
+    if (!$this->isEnabled() || $this->isCli()) {
       return;
     }
 
@@ -294,7 +296,7 @@ public function regenerate($destroy = FALSE, $lifetime = NULL) {
    */
   public function delete($uid) {
     // Nothing to do if we are not allowed to change the session.
-    if (!$this->isEnabled()) {
+    if (!$this->isEnabled() || $this->isCli()) {
       return;
     }
     $this->connection->delete('sessions')
diff --git a/core/lib/Drupal/Core/Session/SessionManagerInterface.php b/core/lib/Drupal/Core/Session/SessionManagerInterface.php
index dc9aa40..b620c66 100644
--- a/core/lib/Drupal/Core/Session/SessionManagerInterface.php
+++ b/core/lib/Drupal/Core/Session/SessionManagerInterface.php
@@ -15,13 +15,6 @@
 interface SessionManagerInterface extends SessionStorageInterface {
 
   /**
-   * Initializes the session handler, starting a session if needed.
-   *
-   * @return $this
-   */
-  public function initialize();
-
-  /**
    * Ends a specific user's session(s).
    *
    * @param int $uid
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
index a120883..7c5ef27 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
@@ -1093,6 +1093,11 @@ protected function rebuildContainer($environment = 'prod') {
     if (\Drupal::getContainer()->initialized('request_stack')) {
       $request_stack = \Drupal::service('request_stack');
     }
+    // If there is a session manager, close and save the session.
+    $has_session_manager = \Drupal::getContainer()->initialized('session_manager');
+    if ($has_session_manager) {
+      \Drupal::getContainer()->get('session_manager')->save();
+    }
 
     $this->kernel = new DrupalKernel($environment, drupal_classloader(), TRUE, FALSE);
     $this->kernel->boot();
@@ -1107,7 +1112,9 @@ protected function rebuildContainer($environment = 'prod') {
     else {
       $this->container->get('request_stack')->push($request);
     }
-    $this->container->get('current_user')->setAccount(\Drupal::currentUser());
+    if ($has_session_manager) {
+      $this->container->get('session_manager');
+    }
 
     // The request context is normally set by the router_listener from within
     // its KernelEvents::REQUEST listener. In the simpletest parent site this
diff --git a/core/update.php b/core/update.php
index b6accf3..40e504c 100644
--- a/core/update.php
+++ b/core/update.php
@@ -342,7 +342,8 @@ function update_task_list($active = NULL) {
 // Determine if the current user has access to run update.php.
 drupal_bootstrap(DRUPAL_BOOTSTRAP_PAGE_CACHE);
 
-\Drupal::service('session_manager')->initialize();
+// Initialize the session manager.
+\Drupal::service('session_manager');
 
 // Ensure that URLs generated for the home and admin pages don't have 'update.php'
 // in them.
