`org.elasticsearch.action.search.AbstractSearchAsyncAction#clusterState` is almost entirely unused, except for one trace log message and one call to `org.elasticsearch.cluster.ClusterState#getMinTransportVersion`. If the cluster state is changing quickly while searches are starting then these captured cluster states can consume substantial memory. If all we care about is the min transport version then we should just pass that in.

Note that the cluster state that ends up here is also captured by various lambdas (e.g. the one that runs after the can-match phase). The more we can reduce the scope of this cluster state capture, the better.
server/src/main/java/org/elasticsearch/action/search/AbstractSearchAsyncAction.java
SearchShardTarget shard,
        SearchActionListener<Result> listener
    );
    protected void fork(final Runnable runnable) {
        executor.execute(new AbstractRunnable() {
            @Override
            public void onFailure(Exception e) {}
            @Override
            protected void doRun() {
                runnable.run();
            }
            @Override
            public boolean isForceExecution() {
                
                return true;
            }
        });
    }
    @Override
    public final void executeNextPhase(SearchPhase currentPhase, SearchPhase nextPhase) {
        /* This is the main search phase transition where we move to the next phase. If all shards
         * failed or if there was a failure and partial results are not allowed, then we immediately
         * fail. Otherwise we continue to the next phase.
         */
        ShardOperationFailedException[] shardSearchFailures = buildShardFailures();
        if (shardSearchFailures.length == getNumShards()) {
            shardSearchFailures = ExceptionsHelper.groupBy(shardSearchFailures);
            Throwable cause = shardSearchFailures.length == 0
                ? null
                : ElasticsearchException.guessRootCauses(shardSearchFailures[0].getCause())[0];