/* * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions.
*/
privatestatic BufferPoolMXBean getDirectPool() { final List<BufferPoolMXBean> pools =
ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class); for (BufferPoolMXBean pool : pools) { if (pool.getName().equals("direct")) { return pool;
}
} thrownew Error("could not find direct pool");
} privatestaticfinal BufferPoolMXBean directPool = getDirectPool(); privatestaticlong initialCount; privatestaticlong initialCapacity;
// Each worker will do write operations on a file channel using // buffers of various sizes. The buffer size is randomly chosen to // be within a small or a large range. This way we can control // which buffers can be cached (all, only the small ones, or none) // by setting the jdk.nio.maxCachedBufferSize property. privatestaticclass Worker implements Runnable { privatefinalint id; privatefinal CountDownLatch finishLatch, exitLatch; private SplittableRandom random = SRAND.split(); privatelong smallBufferCount = 0; privatelong largeBufferCount = 0;
privatevoid loop() { final String fileName = String.format("%s%d", FILE_NAME_PREFIX, id);
try { for (int i = 0; i < iters; i += 1) { finalint writeSize = getWriteSize();
// This will allocate a HeapByteBuffer. It should not // be a direct buffer, otherwise the write() method on // the channel below will not create a temporary // direct buffer for the write. final ByteBuffer buffer = ByteBuffer.allocate(writeSize);
// Put some random data on it. while (buffer.hasRemaining()) {
buffer.put((byte) random.nextInt());
}
buffer.rewind();
final Path file = Paths.get(fileName); try (FileChannel outChannel = FileChannel.open(file, CREATE, TRUNCATE_EXISTING, WRITE)) { // The write() method will create a temporary // direct buffer for the write and attempt to cache // it. It's important that buffer is not a // direct buffer, otherwise the temporary buffer // will not be created. long res = outChannel.write(buffer);
}
if (directCount > expectedCount) { thrownew Error(String.format( "inconsistent direct buffer total count, expected = %d, found = %d",
expectedCount, directCount));
}
if (directTotalCapacity > expectedMax) { thrownew Error(String.format( "inconsistent direct buffer total capacity, expected max = %d, found = %d",
expectedMax, directTotalCapacity));
}
}
// We assume that the max cannot be equal to a size of a // buffer that can be allocated (makes sanity checking at the // end easier). if ((SMALL_BUFFER_MIN_SIZE <= maxBufferSize &&
maxBufferSize <= SMALL_BUFFER_MAX_SIZE) ||
(LARGE_BUFFER_MIN_SIZE <= maxBufferSize &&
maxBufferSize <= LARGE_BUFFER_MAX_SIZE)) { thrownew Error(String.format("max buffer size = %d not allowed",
maxBufferSize));
}
final CountDownLatch finishLatch = new CountDownLatch(threadNum); final CountDownLatch exitLatch = new CountDownLatch(1); finalThread[] threads = newThread[threadNum]; for (int i = 0; i < threadNum; i += 1) {
threads[i] = newThread(new Worker(i, finishLatch, exitLatch));
threads[i].start();
}
// There is an assumption here that, at this point, only the // cached DirectByteBuffers should be active. Given we // haven't used any other DirectByteBuffers in this test, this // should hold. // // Also note that we can only do the sanity checking at the // end and not during the run given that, at any time, there // could be buffers currently in use by some of the workers // that will not be cached.
System.out.println(); if (maxBufferSize < SMALL_BUFFER_MAX_SIZE) { // The max buffer size is smaller than all buffers that // were allocated. No buffers should have been cached.
checkDirectBuffers(0, 0);
} elseif (maxBufferSize < LARGE_BUFFER_MIN_SIZE) { // The max buffer size is larger than all small buffers // but smaller than all large buffers that were // allocated. Only small buffers could have been cached.
checkDirectBuffers(threadNum,
(long) threadNum * (long) SMALL_BUFFER_MAX_SIZE);
} else { // The max buffer size is larger than all buffers that // were allocated. All buffers could have been cached.
checkDirectBuffers(threadNum,
(long) threadNum * (long) LARGE_BUFFER_MAX_SIZE);
}
} finally {
exitLatch.countDown(); try { for (int i = 0; i < threadNum; i += 1) {
threads[i].join();
}
} catch (InterruptedException e) { // ignore
}
}
}
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.