@SuppressWarnings({"OverlyComplexMethod", "JavadocReference", "NestedTryStatement"})
    void reserveMemory(long size) throws MemoryReservationException {
        long availableOrReserved = tryReserveMemory(size);
        // optimist!
        if (availableOrReserved >= size) {
            return;
        }
        // no luck
        throw new MemoryReservationException(
                String.format(
                        "Could not allocate %d bytes, only %d bytes are remaining. This usually indicates "
                                + "that you are requesting more memory than you have reserved. "
                                + "However, when running an old JVM version it can also be caused by slow garbage collection. "
                                + "Try to upgrade to Java 8u72 or higher if running on an old Java version.",
                        size, availableOrReserved));
    }
@Test
    void testReserveMemory() throws MemoryReservationException {
        UnsafeMemoryBudget budget = createUnsafeMemoryBudget();
        budget.reserveMemory(50L);
        assertThat(budget.getAvailableMemorySize()).isEqualTo(50L);
    }