diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php
index 871b859a47edf8d967bc77bac825d004f78eb5a3..88b25bf26903555aa3b1fd16484d171a0292ee94 100644
--- a/core/lib/Drupal/Core/CoreBundle.php
+++ b/core/lib/Drupal/Core/CoreBundle.php
@@ -14,6 +14,7 @@
 use Drupal\Core\DependencyInjection\Compiler\RegisterRouteFiltersPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterRouteEnhancersPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterParamConvertersPass;
+use Drupal\Core\DependencyInjection\Compiler\RegisterServicesForDestructionPass;
 use Symfony\Component\DependencyInjection\ContainerBuilder;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\DependencyInjection\Reference;
@@ -302,6 +303,10 @@ public function build(ContainerBuilder $container) {
 
     $container->register('plugin.manager.condition', 'Drupal\Core\Condition\ConditionManager');
 
+    $container->register('kernel_destruct_subscriber', 'Drupal\Core\EventSubscriber\KernelDestructionSubscriber')
+      ->addMethodCall('setContainer', array(new Reference('service_container')))
+      ->addTag('event_subscriber');
+
     $container->addCompilerPass(new RegisterMatchersPass());
     $container->addCompilerPass(new RegisterRouteFiltersPass());
     // Add a compiler pass for registering event subscribers.
@@ -312,6 +317,8 @@ public function build(ContainerBuilder $container) {
     // Add a compiler pass for upcasting of entity route parameters.
     $container->addCompilerPass(new RegisterParamConvertersPass());
     $container->addCompilerPass(new RegisterRouteEnhancersPass());
+    // Add a compiler pass for registering services needing destruction.
+    $container->addCompilerPass(new RegisterServicesForDestructionPass());
   }
 
   /**
diff --git a/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterServicesForDestructionPass.php b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterServicesForDestructionPass.php
new file mode 100644
index 0000000000000000000000000000000000000000..ab89658f2da223a55a16e902abdce2923e61ffcf
--- /dev/null
+++ b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterServicesForDestructionPass.php
@@ -0,0 +1,34 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\DependencyInjection\Compiler\RegisterServicesForDestructionPass.
+ */
+
+namespace Drupal\Core\DependencyInjection\Compiler;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+
+/**
+ * Adds services tagged "needs_destruction" to the "kernel_destruct_subscriber"
+ * service.
+ */
+class RegisterServicesForDestructionPass implements CompilerPassInterface {
+
+  /**
+   * Implements \Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface::process().
+   */
+  public function process(ContainerBuilder $container) {
+    if (!$container->hasDefinition('kernel_destruct_subscriber')) {
+      return;
+    }
+
+    $definition = $container->getDefinition('kernel_destruct_subscriber');
+
+    $services = $container->findTaggedServiceIds('needs_destruction');
+    foreach ($services as $id => $attributes) {
+      $definition->addMethodCall('registerService', array($id));
+    }
+  }
+}
diff --git a/core/lib/Drupal/Core/DestructableInterface.php b/core/lib/Drupal/Core/DestructableInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..e06c6eca006ad85cc73fe0c9fd39caf326623a29
--- /dev/null
+++ b/core/lib/Drupal/Core/DestructableInterface.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\DestructableInterface.
+ */
+
+namespace Drupal\Core;
+
+/**
+ * The interface for services that need explicit destruction.
+ */
+interface DestructableInterface {
+
+  /**
+   * Performs destruct operations.
+   */
+  public function destruct();
+}
diff --git a/core/lib/Drupal/Core/EventSubscriber/KernelDestructionSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/KernelDestructionSubscriber.php
new file mode 100644
index 0000000000000000000000000000000000000000..e71f5caf347a6b5f1d6ac8446d861e1e71581229
--- /dev/null
+++ b/core/lib/Drupal/Core/EventSubscriber/KernelDestructionSubscriber.php
@@ -0,0 +1,67 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\EventSubscriber\KernelDestructionSubscriber.
+ */
+
+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;
+
+/**
+ * Destructs services that are initiated and tagged with "needs_destruction".
+ */
+class KernelDestructionSubscriber extends ContainerAware implements EventSubscriberInterface {
+
+  /**
+   * Holds an array of service ID's that will require destruction.
+   *
+   * @var array
+   */
+  protected $services = array();
+
+  /**
+   * Registers a service for destruction.
+   *
+   * Calls to this method are set up in
+   * RegisterServicesForDestructionPass::process().
+   *
+   * @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) {
+    foreach ($this->services as $id) {
+      // Check if the service was initialized during this request, destruction
+      // is not necessary if the service was not used.
+      if ($this->container->initialized($id)) {
+        $service = $this->container->get($id);
+        $service->destruct();
+      }
+    }
+  }
+
+  /**
+   * 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 45bdca2ff9324ac754279a2dbe8ae0d047acf66e..06a45005a4df982c4268673656f14c2543266f5a 100644
--- a/core/lib/Drupal/Core/Path/AliasManager.php
+++ b/core/lib/Drupal/Core/Path/AliasManager.php
@@ -23,7 +23,7 @@ class AliasManager implements AliasManagerInterface {
   /**
    * The Key/Value Store to use for state
    *
-   * @var \Drupal\Core\KeyValueStore\DatabaseStorage
+   * @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface
    */
   protected $state;
 
diff --git a/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/ServiceDestructionTest.php b/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/ServiceDestructionTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..1310f697524e7d30f5409c1ef2fdef1c1c0c9d6c
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/ServiceDestructionTest.php
@@ -0,0 +1,68 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\system\Tests\DrupalKernel\ServiceDestructionTest.
+ */
+
+namespace Drupal\system\Tests\DrupalKernel;
+
+use Drupal\simpletest\DrupalUnitTestBase;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\Event\PostResponseEvent;
+
+/**
+ * Tests the service destruction functionality.
+ */
+class ServiceDestructionTest extends DrupalUnitTestBase {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Service destruction',
+      'description' => 'Tests that services are correctly destructed.',
+      'group' => 'DrupalKernel',
+    );
+  }
+
+  /**
+   * Verifies that services are destructed when used.
+   */
+  public function testDestructionUsed() {
+    // Enable the test module to add it to the container.
+    $this->enableModules(array('bundle_test'));
+
+    // The service has not been destructed yet.
+    $this->assertNull(state()->get('bundle_test.destructed'));
+
+    // Get the service destructor.
+    $service_destruction = $this->container->get('kernel_destruct_subscriber');
+
+    // Call the class and then invoke the kernel terminate event.
+    $this->container->get('bundle_test_class');
+    $response = new Response();
+    $event = new PostResponseEvent($this->container->get('kernel'), $this->container->get('request'), $response);
+    $service_destruction->onKernelTerminate($event);
+    $this->assertTrue(state()->get('bundle_test.destructed'));
+  }
+
+  /**
+   * Verifies that services are not unnecessarily destructed when not used.
+   */
+  public function testDestructionUnused() {
+    // Enable the test module to add it to the container.
+    $this->enableModules(array('bundle_test'));
+
+    // The service has not been destructed yet.
+    $this->assertNull(state()->get('bundle_test.destructed'));
+
+    // Get the service destructor.
+    $service_destruction = $this->container->get('kernel_destruct_subscriber');
+
+    // Simulate a shutdown. The test class has not been called, so it should not
+    // be destructed.
+    $response = new Response();
+    $event = new PostResponseEvent($this->container->get('kernel'), $this->container->get('request'), $response);
+    $service_destruction->onKernelTerminate($event);
+    $this->assertNull(state()->get('bundle_test.destructed'));
+  }
+}
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 21a62d51d5a28a48aaf9c68e70381cbdba323090..19b50e17063a31fe37adee7693d786f7af79e120 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_destruction');
 
     // 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 f58f9c9fc455b4bf8d0ed426c1bac4651e0b18f6..ad711cbb9db848ee1a97a0110626a74ca270b368 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\DestructableInterface;
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\HttpKernel\Event\GetResponseEvent;
+use Symfony\Component\HttpKernel\KernelEvents;
 
-class TestClass implements EventSubscriberInterface {
+class TestClass implements EventSubscriberInterface, DestructableInterface {
+
+  /**
+   * 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\DestructableInterface::destruct().
+   */
+  public function destruct() {
+    $this->state->set('bundle_test.destructed', TRUE);
+  }
 }
diff --git a/core/modules/views/lib/Drupal/views/ViewsBundle.php b/core/modules/views/lib/Drupal/views/ViewsBundle.php
index 0b18d3f5b685d7e28e9489b64c4eb82f846a02ef..e4443f8560b3385ecacae994881d52219cd8cdda 100644
--- a/core/modules/views/lib/Drupal/views/ViewsBundle.php
+++ b/core/modules/views/lib/Drupal/views/ViewsBundle.php
@@ -35,7 +35,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_destruction');
 
     $container->register('views.executable', 'Drupal\views\ViewExecutableFactory');
 
diff --git a/core/modules/views/lib/Drupal/views/ViewsDataCache.php b/core/modules/views/lib/Drupal/views/ViewsDataCache.php
index e8d474730c384072482f206113304e58d16d2acd..15e338c74cfabfac334adc260bc37e6371fb70d5 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\DestructableInterface;
 
 /**
  * Class to manage and lazy load cached views data.
  */
-class ViewsDataCache {
+class ViewsDataCache implements DestructableInterface {
 
   /**
    * The base cache ID to use.
@@ -241,25 +242,18 @@ public function fetchBaseTables() {
   }
 
   /**
-   * Destructs the ViewDataCache object.
+   * Implements \Drupal\Core\DestructableInterface::destruct().
    */
-  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 destruct() {
+    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.
-    }
   }
 
 }