## 🐛 Bug Report

If you create new webdriver instances and destroy it in a loop, selenium leaks more and more "Driver Service Executor" and "Driver Command Executor" threads.

After stepping into the code and debuging it, i found that DriverService#close() and DriverCommandExecutor#close() are never called to free the local instances of java.util.concurrent.ExecutorService.

## To Reproduce

Its simple. Create new webdriver instances and shutdown it with WebDriver#quit() in a loop. 

And then just use a tool like VisualVM to see more and more "Driver Service Executor" and "Driver Command Executor" threads are created and not freed. See my sample below:

![image](https://user-images.githubusercontent.com/434996/126345490-6ade3518-2416-4d6b-a4ea-98f640d980b7.png)


## Expected behavior

Release the ExecutorService instances within DriverService and DriverCommandExecutor after a WebDriver#quit() call.

## Test script or set of commands reproducing this issue

```
import java.io.File;
import java.util.UUID;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;


public class LeakTester {

    public static void main( String[] args ) {

        final File browserPath = new File( "src/main/runtime/browsers/chrome_win_91.0.4464.5/chrome.exe" );
        final File driverPath = new File( "src/main/runtime/browsers/chrome_win_91.0.4464.5/chromedriver.exe" );

        System.setProperty( "webdriver.chrome.driver", driverPath.getAbsolutePath() );

        while ( true ) {
            WebDriver driver = null;
            try {
                ChromeOptions options = new ChromeOptions();
                options.setHeadless( true );
                options.setBinary( browserPath );
                options.addArguments( "user-data-dir=" + new File( "./target/leak-test-sessions/session-"
                                                                   + UUID.randomUUID().toString() ).getAbsolutePath() );
                driver = new ChromeDriver( options );

                test( driver );
                driver.close();
            }
            catch ( WebDriverException ex ) {
                ex.printStackTrace();
            }
            finally {
                if ( driver != null ) {
                    try {
                        driver.quit();
                        driver = null;
                    }
                    catch ( WebDriverException ex ) {
                        ex.printStackTrace();
                    }
                }
            }
        }
    }

    static void test( final WebDriver driver ) {
        driver.get( "https://www.selenium.dev/" );
        driver.findElement( By.className( "download-button" ) ).click();
    }
}
```

## Environment

OS: Windows 10
Browser: chrome
Browser version: 91.0.4464.5
Browser Driver version: chromedriver 91.0.4464.5
Language Bindings version: java 4.0.0-beta-4


private int port = 0;
    private File exe = null;
    private Map<String, String> environment = emptyMap();
    private File logFile;
    private Duration timeout;
    /**
     * Provides a measure of how strongly this {@link DriverService} supports the given
     * {@code capabilities}. A score of 0 or less indicates that this {@link DriverService} does not
     * support instances of {@link org.openqa.selenium.WebDriver} that require {@code capabilities}.
     * Typically, the score is generated by summing the number of capabilities that the driver
     * service directly supports that are unique to the driver service (that is, things like
     * "{@code proxy}" don't tend to count to the score).
     */
    public abstract int score(Capabilities capabilities);
    /**
     * Sets which driver executable the builder will use.
     *
     * @param file The executable to use.
     * @return A self reference.
     */
    @SuppressWarnings("unchecked")
    public B usingDriverExecutable(File file) {
      Require.nonNull("Driver executable file", file);
      checkExecutable(file);
      this.exe = file;
      return (B) this;
    }