private void checkSizeAndGrow(int extra) {
    long capacityNeeded = this.pos + (long) extra;
    if (capacityNeeded > this.buf.length) {
      // guarantee it's possible to fit
      if (capacityNeeded > MAX_ARRAY_SIZE) {
        throw new BufferOverflowException();
      }
      // double until hit the cap
      long nextCapacity = Math.min(this.buf.length << 1, MAX_ARRAY_SIZE);
      // but make sure there is enough if twice the existing capacity is still too small
      nextCapacity = Math.max(nextCapacity, capacityNeeded);
      if (nextCapacity > MAX_ARRAY_SIZE) {
        throw new BufferOverflowException();
      }
      byte[] newBuf = new byte[(int) nextCapacity];
      System.arraycopy(buf, 0, newBuf, 0, buf.length);
      buf = newBuf;
    }
  }
Our own implementation of ByteArrayOutputStream where all methods are NOT synchronized and
supports writing ByteBuffer directly to it.
hbase-common/src/main/java/org/apache/hadoop/hbase/io/ByteArrayOutputStream.java