diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php
index e9d6d2f..8742dbd 100644
--- a/core/lib/Drupal/Core/CoreBundle.php
+++ b/core/lib/Drupal/Core/CoreBundle.php
@@ -12,6 +12,7 @@
 use Drupal\Core\DependencyInjection\Compiler\RegisterMatchersPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterNestedMatchersPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterSerializationClassesPass;
+use Drupal\Core\DependencyInjection\Compiler\RegisterServicesForTerminationPass;
 use Symfony\Component\DependencyInjection\ContainerBuilder;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\DependencyInjection\Reference;
@@ -86,9 +87,15 @@ public function build(ContainerBuilder $container) {
       ->register('queue.database', 'Drupal\Core\Queue\QueueDatabaseFactory')
       ->addArgument(new Reference('database'));
 
+    $container
+      ->register('state', 'Drupal\Core\KeyValueStore\KeyValueStoreInterface')
+      ->setFactoryService('keyvalue')
+      ->setFactoryMethod('get')
+      ->addArgument('state');
+
     $container->register('path.alias_manager', 'Drupal\Core\Path\AliasManager')
       ->addArgument(new Reference('database'))
-      ->addArgument(new Reference('keyvalue'));
+      ->addArgument(new Reference('state'));
 
     $container->register('http_client_simpletest_subscriber', 'Drupal\Core\Http\Plugin\SimpletestHttpRequestSubscriber');
     $container->register('http_default_client', 'Guzzle\Http\Client')
@@ -253,6 +260,10 @@ public function build(ContainerBuilder $container) {
     $container->register('flood', 'Drupal\Core\Flood\DatabaseBackend')
       ->addArgument(new Reference('database'));
 
+    $container->register('kernel_terminate_subscriber', 'Drupal\Core\EventSubscriber\KernelTerminateSubscriber')
+      ->addMethodCall('setContainer', array(new Reference('service_container')))
+      ->addTag('event_subscriber');
+
     $container->addCompilerPass(new RegisterMatchersPass());
     $container->addCompilerPass(new RegisterNestedMatchersPass());
     // Add a compiler pass for adding Normalizers and Encoders to Serializer.
@@ -260,6 +271,8 @@ public function build(ContainerBuilder $container) {
     // Add a compiler pass for registering event subscribers.
     $container->addCompilerPass(new RegisterKernelListenersPass(), PassConfig::TYPE_AFTER_REMOVING);
     $container->addCompilerPass(new RegisterAccessChecksPass());
+    // Add a compiler pass for registering services needing termination.
+    $container->addCompilerPass(new RegisterServicesForTerminationPass());
   }
 
   /**
diff --git a/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterServicesForTerminationPass.php b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterServicesForTerminationPass.php
new file mode 100644
index 0000000..d936fb3
--- /dev/null
+++ b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterServicesForTerminationPass.php
@@ -0,0 +1,46 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\DependencyInjection\Compiler\RegisterServicesForTerminationPass.
+ */
+
+namespace Drupal\Core\DependencyInjection\Compiler;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+
+/**
+ * Registers needs_termination tagged services with service_terminator.
+ */
+class RegisterServicesForTerminationPass implements CompilerPassInterface {
+
+  /**
+   * Implements CompilerPassInterface::process().
+   */
+  public function process(ContainerBuilder $container) {
+    if (!$container->hasDefinition('kernel_terminate_subscriber')) {
+      return;
+    }
+
+    $definition = $container->getDefinition('kernel_terminate_subscriber');
+
+    // Reverse the order of tagged services to terminate them in the opposite
+    // order of which they are defined.
+    // @todo: Does this need a better system to detect references?
+    $services = array_reverse($container->findTaggedServiceIds('needs_termination'));
+    foreach ($services as $id => $attributes) {
+
+      // We must assume that the class value has been correcly filled, even if
+      // the service is created by a factory.
+      $class = $container->getDefinition($id)->getClass();
+
+      $refClass = new \ReflectionClass($class);
+      $interface = 'Drupal\Core\TerminationInterface';
+      if (!$refClass->implementsInterface($interface)) {
+        throw new \InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface));
+      }
+      $definition->addMethodCall('registerService', array($id));
+    }
+  }
+}
diff --git a/core/lib/Drupal/Core/EventSubscriber/KernelTerminateSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/KernelTerminateSubscriber.php
new file mode 100644
index 0000000..51fbaf5
--- /dev/null
+++ b/core/lib/Drupal/Core/EventSubscriber/KernelTerminateSubscriber.php
@@ -0,0 +1,74 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\EventSubscriber\KernelTerminateSubscriber.
+ */
+
+namespace Drupal\Core\EventSubscriber;
+
+use Symfony\Component\DependencyInjection\ContainerAware;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\HttpKernel\Event\PostResponseEvent;
+use Symfony\Component\HttpKernel\KernelEvents;
+
+/**
+ * This terminates iniated services tagged with needs_termination.
+ */
+class KernelTerminateSubscriber extends ContainerAware implements EventSubscriberInterface {
+
+  /**
+   * Holds an array of service ID's that will require termination.
+   *
+   * @var array
+   */
+  protected $services;
+
+  /**
+   * Registers a a service for termination.
+   *
+   * Calls to this method are set up in
+   * RegisterServicesForTerminationPass::terminate().
+   *
+   * @param string $id
+   *   Name of the service.
+   */
+  public function registerService($id) {
+    $this->services[] = $id;
+  }
+
+  /**
+   * Invoked by the terminate kernel event.
+   *
+   * @param \Symfony\Component\HttpKernel\Event\PostResponseEvent $event
+   *   The event object.
+   */
+  public function onKernelTerminate(PostResponseEvent $event) {
+    $this->terminateInitiatedServices();
+  }
+
+  /**
+   * Terminates registered services if necessary.
+   */
+  protected function terminateInitiatedServices() {
+    foreach ($this->services as $id) {
+      // Check if the service was initialized during this request, termination
+      // is not necessary if the service was not used.
+      if ($this->container->initialized($id)) {
+        $service = $this->container->get($id);
+        $service->terminate();
+      }
+    }
+  }
+
+  /**
+   * Registers the methods in this class that should be listeners.
+   *
+   * @return array
+   *   An array of event listener definitions.
+   */
+  static function getSubscribedEvents() {
+    $events[KernelEvents::TERMINATE][] = array('onKernelTerminate', 100);
+    return $events;
+  }
+}
diff --git a/core/lib/Drupal/Core/Path/AliasManager.php b/core/lib/Drupal/Core/Path/AliasManager.php
index 47bf77b..b34f178 100644
--- a/core/lib/Drupal/Core/Path/AliasManager.php
+++ b/core/lib/Drupal/Core/Path/AliasManager.php
@@ -78,9 +78,9 @@ class AliasManager implements AliasManagerInterface {
    */
   protected $preloadedPathLookups = array();
 
-  public function __construct(Connection $connection, KeyValueFactory $keyvalue) {
+  public function __construct(Connection $connection, KeyValueStoreInterface $state) {
     $this->connection = $connection;
-    $this->state = $keyvalue->get('state');
+    $this->state = $state;
     $this->langcode = language(LANGUAGE_TYPE_URL)->langcode;
     $this->whitelist = $this->state->get('system.path_alias_whitelist', NULL);
     if (!isset($this->whitelist)) {
diff --git a/core/lib/Drupal/Core/TerminationInterface.php b/core/lib/Drupal/Core/TerminationInterface.php
new file mode 100644
index 0000000..d4f169f
--- /dev/null
+++ b/core/lib/Drupal/Core/TerminationInterface.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\TerminationInterface.
+ */
+
+namespace Drupal\Core;
+
+/**
+ * The interface for services needing explicit termination.
+ */
+interface TerminationInterface {
+
+  /**
+   * Performs termination operations.
+   */
+  public function terminate();
+}
diff --git a/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/ServiceTerminatorTest.php b/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/ServiceTerminatorTest.php
new file mode 100644
index 0000000..f00dfc1
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/ServiceTerminatorTest.php
@@ -0,0 +1,53 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\system\Tests\DrupalKernel\ServiceTerminatorTest.
+ */
+
+namespace Drupal\system\Tests\DrupalKernel;
+
+use Drupal\simpletest\DrupalUnitTestBase;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\Event\PostResponseEvent;
+
+/**
+ * Tests the service terminator service.
+ */
+class ServiceTerminatorTest extends DrupalUnitTestBase {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Service terminator',
+      'description' => 'Tests that services are correctly terminated.',
+      'group' => 'DrupalKernel',
+    );
+  }
+
+  /**
+   * Verifies that services are correctly terminated.
+   */
+  public function testTermination() {
+    // Enable the test module to add it to the container.
+    $this->enableModules(array('bundle_test'));
+
+    // The service has not been terminated yet.
+    $this->assertNull(state()->get('bundle_test.terminated'));
+
+    // Get the service terminator.
+    $service_terminator = $this->container->get('kernel_terminate_subscriber');
+
+    // Simulate a shutdown. The test class has not been called, so it should not
+    // be terminated.
+    $response = new Response();
+    $event = new PostResponseEvent($this->container->get('kernel'), $this->container->get('request'), $response);
+    $service_terminator->onKernelTerminate($event);
+    $this->assertNull(state()->get('bundle_test.terminated'));
+
+    // Now call the class and then terminate again.
+    $this->container->get('bundle_test_class');
+    $service_terminator->onKernelTerminate($event);
+    $this->assertTrue(state()->get('bundle_test.terminated'));
+  }
+
+}
diff --git a/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/GarbageCollectionTest.php b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/GarbageCollectionTest.php
index 6334382..925c928 100644
--- a/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/GarbageCollectionTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/KeyValueStore/GarbageCollectionTest.php
@@ -65,7 +65,7 @@ public function testGarbageCollection() {
     // Perform a new set operation and then manually unset the object to
     // trigger garbage collection.
     $store->setWithExpire('autumn', 'winter', rand(500, 1000000));
-    unset($store);
+    $store->terminate();
 
     // Query the database and confirm that the stale records were deleted.
     $result = db_query(
diff --git a/core/modules/system/lib/Drupal/system/Tests/Path/AliasTest.php b/core/modules/system/lib/Drupal/system/Tests/Path/AliasTest.php
index 21a129a..23e4d08 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Path/AliasTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Path/AliasTest.php
@@ -43,7 +43,7 @@ function testCRUD() {
     $this->fixtures->createTables($connection);
 
     //Create AliasManager and Path object.
-    $aliasManager = new AliasManager($connection, $this->container->get('keyvalue'));
+    $aliasManager = new AliasManager($connection, $this->container->get('keyvalue')->get('state'));
     $path = new Path($connection, $aliasManager);
 
     $aliases = $this->fixtures->sampleUrlAliases();
@@ -96,7 +96,7 @@ function testLookupPath() {
     $this->fixtures->createTables($connection);
 
     //Create AliasManager and Path object.
-    $aliasManager = new AliasManager($connection, $this->container->get('keyvalue'));
+    $aliasManager = new AliasManager($connection, $this->container->get('keyvalue')->get('state'));
     $pathObject = new Path($connection, $aliasManager);
 
     // Test the situation where the source is the same for multiple aliases.
diff --git a/core/modules/system/tests/modules/bundle_test/lib/Drupal/bundle_test/BundleTestBundle.php b/core/modules/system/tests/modules/bundle_test/lib/Drupal/bundle_test/BundleTestBundle.php
index 21a62d5..bb12dac 100644
--- a/core/modules/system/tests/modules/bundle_test/lib/Drupal/bundle_test/BundleTestBundle.php
+++ b/core/modules/system/tests/modules/bundle_test/lib/Drupal/bundle_test/BundleTestBundle.php
@@ -19,7 +19,9 @@ class BundleTestBundle extends Bundle
 {
   public function build(ContainerBuilder $container) {
     $container->register('bundle_test_class', 'Drupal\bundle_test\TestClass')
-      ->addTag('event_subscriber');
+      ->addArgument(new Reference('state'))
+      ->addTag('event_subscriber')
+      ->addTag('needs_termination');
 
     // Override a default bundle used by core to a dummy class.
     $container->register('file.usage', 'Drupal\bundle_test\TestFileUsage');
diff --git a/core/modules/system/tests/modules/bundle_test/lib/Drupal/bundle_test/TestClass.php b/core/modules/system/tests/modules/bundle_test/lib/Drupal/bundle_test/TestClass.php
index f58f9c9..ce5f72a 100644
--- a/core/modules/system/tests/modules/bundle_test/lib/Drupal/bundle_test/TestClass.php
+++ b/core/modules/system/tests/modules/bundle_test/lib/Drupal/bundle_test/TestClass.php
@@ -7,11 +7,30 @@
 
 namespace Drupal\bundle_test;
 
-use Symfony\Component\HttpKernel\KernelEvents;
-use Symfony\Component\HttpKernel\Event\GetResponseEvent;
+use Drupal\Core\KeyValueStore\KeyValueStoreInterface;
+use Drupal\Core\TerminationInterface;
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\HttpKernel\Event\GetResponseEvent;
+use Symfony\Component\HttpKernel\KernelEvents;
 
-class TestClass implements EventSubscriberInterface {
+class TestClass implements EventSubscriberInterface, TerminationInterface {
+
+  /**
+   * The state keyvalue collection.
+   *
+   * @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface
+   */
+  protected $state;
+
+  /**
+   * Constructor.
+   *
+   * @param \Drupal\Core\KeyValueStore\KeyValueStoreInterface $state
+   *   The state key value store.
+   */
+  public function __construct(KeyValueStoreInterface $state) {
+    $this->state = $state;
+  }
 
   /**
    * A simple kernel listener method.
@@ -30,4 +49,11 @@ static function getSubscribedEvents() {
     $events[KernelEvents::REQUEST][] = array('onKernelRequestTest', 100);
     return $events;
   }
+
+  /**
+   * Implements \Drupal\Core\TerminationInterface::terminate().
+   */
+  public function terminate() {
+    $this->state->set('bundle_test.terminated', TRUE);
+  }
 }
diff --git a/core/modules/views/lib/Drupal/views/ViewsBundle.php b/core/modules/views/lib/Drupal/views/ViewsBundle.php
index 544b8c3..676246d 100644
--- a/core/modules/views/lib/Drupal/views/ViewsBundle.php
+++ b/core/modules/views/lib/Drupal/views/ViewsBundle.php
@@ -34,7 +34,8 @@ public function build(ContainerBuilder $container) {
 
     $container->register('views.views_data', 'Drupal\views\ViewsDataCache')
       ->addArgument(new Reference('cache.views_info'))
-      ->addArgument(new Reference('config.factory'));
+      ->addArgument(new Reference('config.factory'))
+      ->addTag('needs_termination');
   }
 
 }
diff --git a/core/modules/views/lib/Drupal/views/ViewsDataCache.php b/core/modules/views/lib/Drupal/views/ViewsDataCache.php
index 8aec87e..32c9072 100644
--- a/core/modules/views/lib/Drupal/views/ViewsDataCache.php
+++ b/core/modules/views/lib/Drupal/views/ViewsDataCache.php
@@ -7,13 +7,14 @@
 
 namespace Drupal\views;
 
-use Drupal\Core\Config\ConfigFactory;
 use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Config\ConfigFactory;
+use Drupal\Core\TerminationInterface;
 
 /**
  * Class to manage and lazy load cached views data.
  */
-class ViewsDataCache {
+class ViewsDataCache implements TerminationInterface {
 
   /**
    * The base cache ID to use.
@@ -206,23 +207,16 @@ protected function processEntityTypes(array &$data) {
   /**
    * Destructs the ViewDataCache object.
    */
-  public function __destruct() {
-    try {
-      if ($this->rebuildCache && !empty($this->storage)) {
-        // Keep a record with all data.
-        $this->set($this->baseCid, $this->storage);
-        // Save data in seperate cache entries.
-        foreach ($this->storage as $table => $data) {
-          $cid = $this->baseCid . ':' . $table;
-          $this->set($cid, $data);
-        }
+  public function terminate() {
+    if ($this->rebuildCache && !empty($this->storage)) {
+      // Keep a record with all data.
+      $this->set($this->baseCid, $this->storage);
+      // Save data in seperate cache entries.
+      foreach ($this->storage as $table => $data) {
+        $cid = $this->baseCid . ':' . $table;
+        $this->set($cid, $data);
       }
     }
-    catch (\Exception $e) {
-      // During testing the table is gone before this fires.
-      // @todo Use terminate() instead of __destruct(), see
-      //   http://drupal.org/node/512026.
-    }
   }
 
 }
