@Override
    public void close() {
      ThreadContext context = ourContext.get();
      places.clear();
      if (context.topFrame != this) {
        LOG.warn("unexpected frame: " + (context.topFrame == null ? "null" : context.topFrame.id) + ", expected: " + id , new Throwable());
      }
      context.topFrame = parent;
      if (parent == null) {
        ourContext.remove(); // also releases ThreadContext.consumer reference
      }
      if (context.consumer == null || context.epoch != ourGlobalContext.epoch) return;

      context.consumer.onFrameExit(id, start, timeComputed, currentTime());
      long cur = currentTime();
      ourFrameOverhead.total.addAndGet(cur - start);
      if (timeComputed != 0) {
        ourFrameOverhead.overhead.addAndGet(cur - timeComputed);
      }
    }
@Override
    public void close()