`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
/**
     * Builds how long it took to execute the search.
     */
    long buildTookInMillis() {
        return timeProvider.buildTookInMillis();
    }
    /**
     * This is the main entry point for a search. This method starts the search execution of the initial phase.
     */
    public final void start() {
        if (getNumShards() == 0) {
            
            
            int trackTotalHitsUpTo = request.source() == null ? SearchContext.DEFAULT_TRACK_TOTAL_HITS_UP_TO
                : request.source().trackTotalHitsUpTo() == null ? SearchContext.DEFAULT_TRACK_TOTAL_HITS_UP_TO
                : request.source().trackTotalHitsUpTo();
            
            boolean withTotalHits = trackTotalHitsUpTo != SearchContext.TRACK_TOTAL_HITS_DISABLED;
            sendSearchResponse(
                withTotalHits ? InternalSearchResponse.EMPTY_WITH_TOTAL_HITS : InternalSearchResponse.EMPTY_WITHOUT_TOTAL_HITS,
                new AtomicArray<>(0)
            );
            return;
        }
        executePhase(this);
    }
    @Override
    public final void run() {
        for (final SearchShardIterator iterator : toSkipShardsIts) {
            assert iterator.skip();