public void sample(long nanosTimeStamp) {
    final boolean isDebugEnabled_STATISTICS = logger.isTraceEnabled(LogMarker.STATISTICS_VERBOSE);
    if (isDebugEnabled_STATISTICS) {
      logger.trace(LogMarker.STATISTICS_VERBOSE, "SampleCollector#sample nanosTimeStamp={}",
          nanosTimeStamp);
    }
    List<MarkableSampleHandler> handlers = sampleHandlers.currentHandlers();
    if (isDebugEnabled_STATISTICS) {
      logger.trace(LogMarker.STATISTICS_VERBOSE, "SampleCollector#sample handlers={}", handlers);
    }
    sampleResources(handlers);

    List<ResourceInstance> updatedResources = new ArrayList<>();
    for (ResourceInstance ri : resourceInstMap.values()) {
      StatisticDescriptor[] stats = ri.getResourceType().getStatisticDescriptors();
      if (ri.getStatistics().isClosed()) {
        continue;
      }

      // size updatedStats to same size as stats in case all stats changed
      int[] updatedStats = new int[stats.length];
      long[] statValues = ri.getPreviousStatValues();

      if (statValues == null) {
        statValues = new long[stats.length];
        for (int i = 0; i < stats.length; i++) {
          statValues[i] = ri.getRawStatValue(stats[i]);
          updatedStats[i] = i;
        }

      } else {
        statValues = Arrays.copyOf(statValues, statValues.length);
        int updatedStatsIdx = 0;
        for (int i = 0; i < stats.length; i++) {
          long value = ri.getRawStatValue(stats[i]);
          if (value != statValues[i]) {
            statValues[i] = value;
            updatedStats[updatedStatsIdx] = i;
            updatedStatsIdx++;
          }
        }
        // resize updatedStats to only contain the the stats which were updated
        updatedStats = Arrays.copyOf(updatedStats, updatedStatsIdx);
      }

      ri.setUpdatedStats(updatedStats);
      ri.setLatestStatValues(statValues);
      ri.setLatestStatArchiveValues(statValues);
      updatedResources.add(ri);
    }

    try {
      notifyAllHandlersOfSample(handlers, updatedResources, nanosTimeStamp);
    } catch (IllegalArgumentException e) {
      logger.warn(LogMarker.STATISTICS_MARKER,
          "Use of java.lang.System.nanoTime() resulted in a non-positive timestamp delta. Skipping notification of statistics sample.",
          e);
    }

    for (ResourceInstance ri : updatedResources) {
      if (ri.getStatValuesNotified()) {
        ri.setPreviousStatValues(ri.getLatestStatValues());
      }
    }
  }
Collect a sample of all statistics. Adds new statistics resources, removes destroyed statistics
resources, collects the latest stat values, and notifies SamplerHandlers of the sample.
<p>
The timeStamp is an arbitrary nanoseconds time stamp only used for archiving to stats files.
The initial time in system milliseconds and the first NanoTimer timeStamp are both written to
the archive file. Thereafter only the NanoTimer timeStamp is written to the archive file for
each sample. The delta in nanos can be determined by comparing any nano timeStamp to the first
nano timeStamp written to the archive file. Adding this delta to the recorded initial time in
milliseconds provides the actual (non-arbitrary) time for each sample.

@param nanosTimeStamp an arbitrary time stamp in nanoseconds for this sample
geode-core/src/main/java/org/apache/geode/internal/statistics/SampleCollector.java