diff --git a/core/lib/Drupal/Core/Extension/ModuleInstaller.php b/core/lib/Drupal/Core/Extension/ModuleInstaller.php
index 10fabd4..3ff644e 100644
--- a/core/lib/Drupal/Core/Extension/ModuleInstaller.php
+++ b/core/lib/Drupal/Core/Extension/ModuleInstaller.php
@@ -498,34 +498,30 @@ class ModuleInstaller implements ModuleInstallerInterface {
    *   The name of the module for which to remove all registered cache bins.
    */
   protected function removeCacheBins($module) {
-    // Remove any cache bins defined by a module.
     $service_yaml_file = drupal_get_path('module', $module) . "/$module.services.yml";
-    if (file_exists($service_yaml_file)) {
-      $definitions = Yaml::decode(file_get_contents($service_yaml_file));
-      if (isset($definitions['services'])) {
-        foreach ($definitions['services'] as $id => $definition) {
-          if (isset($definition['tags'])) {
-            foreach ($definition['tags'] as $tag) {
-              // This works for the default cache registration and even in some
-              // cases when a non-default "super" factory is used. That should
-              // be extremely rare.
-              if ($tag['name'] == 'cache.bin' && isset($definition['factory_service']) && isset($definition['factory_method']) && !empty($definition['arguments'])) {
-                try {
-                  $factory = \Drupal::service($definition['factory_service']);
-                  if (method_exists($factory, $definition['factory_method'])) {
-                    $backend = call_user_func_array([$factory, $definition['factory_method']], $definition['arguments']);
-                    if ($backend instanceof CacheBackendInterface) {
-                      $backend->removeBin();
-                    }
-                  }
-                }
-                catch (\Exception $e) {
-                  watchdog_exception('system', $e, 'Failed to remove cache bin defined by the service %id.', ['%id' => $id]);
-                }
-              }
-            }
+    if (!file_exists($service_yaml_file)) {
+      return;
+    }
+
+    $definitions = Yaml::decode(file_get_contents($service_yaml_file));
+
+    $cache_bin_services_ids = array_map(
+      function($definition) {
+        $tags = isset($definition['tags']) ? $definition['tags'] : [];
+        foreach ($tags as $tag) {
+          if (isset($tag['name']) && ($tag['name'] == 'cache.bin')) {
+            return TRUE;
           }
         }
+        return FALSE;
+      },
+      isset($definitions['services']) ? $definitions['services'] : []
+    );
+
+    foreach (array_keys($cache_bin_services_ids) as $service_id) {
+      $backend = $this->kernel->getContainer()->get($service_id);
+      if ($backend instanceof CacheBackendInterface) {
+        $backend->removeBin();
       }
     }
   }
diff --git a/core/modules/system/tests/modules/module_cachebin/module_cachebin.info.yml b/core/modules/system/tests/modules/module_cachebin/module_cachebin.info.yml
new file mode 100644
index 0000000..d255795
--- /dev/null
+++ b/core/modules/system/tests/modules/module_cachebin/module_cachebin.info.yml
@@ -0,0 +1,7 @@
+name: module cache bin tests
+type: module
+description: Test cache bins defined by modules.
+package: Testing
+version: VERSION
+core: 8.x
+hidden: true
diff --git a/core/modules/system/tests/modules/module_cachebin/module_cachebin.services.yml b/core/modules/system/tests/modules/module_cachebin/module_cachebin.services.yml
new file mode 100644
index 0000000..8e14274
--- /dev/null
+++ b/core/modules/system/tests/modules/module_cachebin/module_cachebin.services.yml
@@ -0,0 +1,7 @@
+services:
+  module_cachebin.cache_bin:
+    class: Drupal\Core\Cache\CacheBackendInterface
+    tags:
+      - { name: cache.bin }
+    factory: cache.backend.database:get
+    arguments: [module_cachebin]
diff --git a/core/tests/Drupal/KernelTests/Core/Extension/ModuleInstallerTest.php b/core/tests/Drupal/KernelTests/Core/Extension/ModuleInstallerTest.php
index fa5a9a1..0aa654e 100644
--- a/core/tests/Drupal/KernelTests/Core/Extension/ModuleInstallerTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Extension/ModuleInstallerTest.php
@@ -60,4 +60,29 @@ class ModuleInstallerTest extends KernelTestBase {
     $this->assertEquals(1, $modules['module_handler_test_multiple_child'], 'Weight of module_handler_test_multiple_child is set.');
   }
 
+  /**
+   * Tests cache bins defined by removed when modules are uninstalled.
+   *
+   * @covers ::removeCacheBins
+   */
+  public function testCacheBinCleanup() {
+    $schema = $this->container->get('database');
+    $table = 'cache_module_cachebin';
+
+    $module_installer = $this->container->get('module_installer');
+    $module_installer->install(['module_cachebin']);
+
+    // Prime the bin.
+    /** @var \Drupal\Core\Cache\CacheBackendInterface $cache_bin */
+    $cache_bin = $this->container->get('module_cachebin.cache_bin');
+    $cache_bin->set('foo', 'bar');
+
+    // A database backend is used so there is a convenient way check whether the
+    // backend is uninstalled.
+    $this->assertTrue($schema->tableExists($table));
+
+    $module_installer->uninstall(['module_cachebin']);
+    $this->assertFalse($schema->tableExists($table));
+  }
+
 }
