百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

聊聊openjdk的BufferPoolMXBean

toyiye 2024-05-25 20:12 19 浏览 0 评论

本文主要研究一下openjdk的BufferPoolMXBean

PlatformManagedObject

java.management/java/lang/management/PlatformManagedObject.java

public interface PlatformManagedObject {
 /**
 * Returns an {@link ObjectName ObjectName} instance representing
 * the object name of this platform managed object.
 *
 * @return an {@link ObjectName ObjectName} instance representing
 * the object name of this platform managed object.
 */
 public ObjectName getObjectName();
}

PlatformManagedObject接口定义了getObjectName方法用于返回ObjectName

BufferPoolMXBean

java.management/java/lang/management/BufferPoolMXBean.java

public interface BufferPoolMXBean extends PlatformManagedObject {
?
 /**
 * Returns the name representing this buffer pool.
 *
 * @return The name of this buffer pool.
 */
 String getName();
?
 /**
 * Returns an estimate of the number of buffers in the pool.
 *
 * @return An estimate of the number of buffers in this pool
 */
 long getCount();
?
 /**
 * Returns an estimate of the total capacity of the buffers in this pool.
 * A buffer's capacity is the number of elements it contains and the value
 * returned by this method is an estimate of the total capacity of buffers
 * in the pool in bytes.
 *
 * @return An estimate of the total capacity of the buffers in this pool
 * in bytes
 */
 long getTotalCapacity();
?
 /**
 * Returns an estimate of the memory that the Java virtual machine is using
 * for this buffer pool. The value returned by this method may differ
 * from the estimate of the total {@link #getTotalCapacity capacity} of
 * the buffers in this pool. This difference is explained by alignment,
 * memory allocator, and other implementation specific reasons.
 *
 * @return An estimate of the memory that the Java virtual machine is using
 * for this buffer pool in bytes, or {@code -1L} if an estimate of
 * the memory usage is not available
 */
 long getMemoryUsed();
}
  • BufferPoolMXBean接口继承了PlatformManagedObject,它定义了getName、getCount、getTotalCapacity、getMemoryUsed方法

ManagementFactoryHelper

java.management/sun/management/ManagementFactoryHelper.java

public class ManagementFactoryHelper {
 static {
 // make sure that the management lib is loaded within
 // java.lang.management.ManagementFactory
 jdk.internal.misc.Unsafe.getUnsafe().ensureClassInitialized(ManagementFactory.class);
 }
?
 private static final VMManagement jvm = new VMManagementImpl();
?
 private ManagementFactoryHelper() {};
?
 public static VMManagement getVMManagement() {
 return jvm;
 }
?
 static final String LOGGING_MXBEAN_NAME = "java.util.logging:type=Logging";
 private static ClassLoadingImpl classMBean = null;
 private static MemoryImpl memoryMBean = null;
 private static ThreadImpl threadMBean = null;
 private static RuntimeImpl runtimeMBean = null;
 private static CompilationImpl compileMBean = null;
 private static BaseOperatingSystemImpl osMBean = null;
?
 //......
?
 private static List<BufferPoolMXBean> bufferPools = null;
 public static synchronized List<BufferPoolMXBean> getBufferPoolMXBeans() {
 if (bufferPools == null) {
 bufferPools = new ArrayList<>(2);
 bufferPools.add(createBufferPoolMXBean(SharedSecrets.getJavaNioAccess()
 .getDirectBufferPool()));
 bufferPools.add(createBufferPoolMXBean(sun.nio.ch.FileChannelImpl
 .getMappedBufferPool()));
 }
 return bufferPools;
 }
?
 private static BufferPoolMXBean
 createBufferPoolMXBean(final JavaNioAccess.BufferPool pool)
 {
 return new BufferPoolMXBean() {
 private volatile ObjectName objname; // created lazily
 @Override
 public ObjectName getObjectName() {
 ObjectName result = objname;
 if (result == null) {
 synchronized (this) {
 result = objname;
 if (result == null) {
 result = Util.newObjectName(BUFFER_POOL_MXBEAN_NAME +
 ",name=" + pool.getName());
 objname = result;
 }
 }
 }
 return result;
 }
 @Override
 public String getName() {
 return pool.getName();
 }
 @Override
 public long getCount() {
 return pool.getCount();
 }
 @Override
 public long getTotalCapacity() {
 return pool.getTotalCapacity();
 }
 @Override
 public long getMemoryUsed() {
 return pool.getMemoryUsed();
 }
 };
 }
?
 //......
}
  • ManagementFactoryHelper的getBufferPoolMXBeans方法会通过createBufferPoolMXBean方法创建两个BufferPoolMXBean,然后添加到bufferPools
  • 其中一个是DirectBufferPool,一个是MappedBufferPool;他们分别使用SharedSecrets.getJavaNioAccess().getDirectBufferPool()以及sun.nio.ch.FileChannelImpl.getMappedBufferPool()来创建
  • createBufferPoolMXBean方法使用匿名类创建了BufferPoolMXBean的实现;createBufferPoolMXBean方法接收JavaNioAccess.BufferPool参数,其getCount、getTotalCapacity、getMemoryUsed等均是直接使用pool的相关方法

JavaNioAccess.BufferPool

java.base/jdk/internal/access/JavaNioAccess.java

public interface JavaNioAccess {
 /**
 * Provides access to information on buffer usage.
 */
 interface BufferPool {
 String getName();
 long getCount();
 long getTotalCapacity();
 long getMemoryUsed();
 }
 BufferPool getDirectBufferPool();
}
  • JavaNioAccess里头定义了BufferPool接口,它定义了getName、getCount、getTotalCapacity、getMemoryUsed方法;除此之外JavaNioAccess还定义了getDirectBufferPool方法用于返回BufferPool

SharedSecrets

java.base/jdk/internal/access/SharedSecrets.java

public class SharedSecrets {
 private static final Unsafe unsafe = Unsafe.getUnsafe();
 private static JavaUtilJarAccess javaUtilJarAccess;
 private static JavaLangAccess javaLangAccess;
 private static JavaLangModuleAccess javaLangModuleAccess;
 private static JavaLangInvokeAccess javaLangInvokeAccess;
 private static JavaLangRefAccess javaLangRefAccess;
 private static JavaIOAccess javaIOAccess;
 private static JavaNetInetAddressAccess javaNetInetAddressAccess;
 private static JavaNetHttpCookieAccess javaNetHttpCookieAccess;
 private static JavaNetSocketAccess javaNetSocketAccess;
 private static JavaNetUriAccess javaNetUriAccess;
 private static JavaNetURLAccess javaNetURLAccess;
 private static JavaNetURLClassLoaderAccess javaNetURLClassLoaderAccess;
 private static JavaNioAccess javaNioAccess;
 private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
 private static JavaIOFilePermissionAccess javaIOFilePermissionAccess;
 private static JavaSecurityAccess javaSecurityAccess;
 private static JavaUtilZipFileAccess javaUtilZipFileAccess;
 private static JavaUtilResourceBundleAccess javaUtilResourceBundleAccess;
 private static JavaAWTAccess javaAWTAccess;
 private static JavaAWTFontAccess javaAWTFontAccess;
 private static JavaBeansAccess javaBeansAccess;
 private static JavaObjectInputStreamAccess javaObjectInputStreamAccess;
 private static JavaObjectInputFilterAccess javaObjectInputFilterAccess;
 private static JavaIORandomAccessFileAccess javaIORandomAccessFileAccess;
 private static JavaxCryptoSealedObjectAccess javaxCryptoSealedObjectAccess;
?
 //......
?
 public static void setJavaNioAccess(JavaNioAccess jna) {
 javaNioAccess = jna;
 }
?
 public static JavaNioAccess getJavaNioAccess() {
 if (javaNioAccess == null) {
 // Ensure java.nio.Buffer is initialized, which provides the
 // shared secret.
 unsafe.ensureClassInitialized(java.nio.Buffer.class);
 }
 return javaNioAccess;
 }
?
 //......
}
  • SharedSecrets提供了JavaNioAccess的getter及setter

Buffer

java.base/java/nio/Buffer.java

public abstract class Buffer {
 // Cached unsafe-access object
 static final Unsafe UNSAFE = Unsafe.getUnsafe();
?
 /**
 * The characteristics of Spliterators that traverse and split elements
 * maintained in Buffers.
 */
 static final int SPLITERATOR_CHARACTERISTICS =
 Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED;
?
 // Invariants: mark <= position <= limit <= capacity
 private int mark = -1;
 private int position = 0;
 private int limit;
 private int capacity;
?
 // Used by heap byte buffers or direct buffers with Unsafe access
 // For heap byte buffers this field will be the address relative to the
 // array base address and offset into that array. The address might
 // not align on a word boundary for slices, nor align at a long word
 // (8 byte) boundary for byte[] allocations on 32-bit systems.
 // For direct buffers it is the start address of the memory region. The
 // address might not align on a word boundary for slices, nor when created
 // using JNI, see NewDirectByteBuffer(void*, long).
 // Should ideally be declared final
 // NOTE: hoisted here for speed in JNI GetDirectBufferAddress
 long address;
?
 //......
?
 static {
 // setup access to this package in SharedSecrets
 SharedSecrets.setJavaNioAccess(
 new JavaNioAccess() {
 @Override
 public JavaNioAccess.BufferPool getDirectBufferPool() {
 return Bits.BUFFER_POOL;
 }
 });
 }
?
}
  • 抽象类Buffer有个static代码块,里头创建了匿名JavaNioAccess,然后设置到了SharedSecrets中;其中匿名JavaNioAccess的getDirectBufferPool方法返回的是Bits.BUFFER_POOL

FileChannelImpl

java.base/sun/nio/ch/FileChannelImpl.java

public class FileChannelImpl
 extends FileChannel
{
 // Memory allocation size for mapping buffers
 private static final long allocationGranularity;
?
 // Access to FileDescriptor internals
 private static final JavaIOFileDescriptorAccess fdAccess =
 SharedSecrets.getJavaIOFileDescriptorAccess();
?
 // Used to make native read and write calls
 private final FileDispatcher nd;
?
 // File descriptor
 private final FileDescriptor fd;
?
 //......
?
 // -- Memory-mapped buffers --
?
 private static class Unmapper
 implements Runnable
 {
 // may be required to close file
 private static final NativeDispatcher nd = new FileDispatcherImpl();
?
 // keep track of mapped buffer usage
 static volatile int count;
 static volatile long totalSize;
 static volatile long totalCapacity;
?
 private volatile long address;
 private final long size;
 private final int cap;
 private final FileDescriptor fd;
?
 private Unmapper(long address, long size, int cap,
 FileDescriptor fd)
 {
 assert (address != 0);
 this.address = address;
 this.size = size;
 this.cap = cap;
 this.fd = fd;
?
 synchronized (Unmapper.class) {
 count++;
 totalSize += size;
 totalCapacity += cap;
 }
 }
?
 public void run() {
 if (address == 0)
 return;
 unmap0(address, size);
 address = 0;
?
 // if this mapping has a valid file descriptor then we close it
 if (fd.valid()) {
 try {
 nd.close(fd);
 } catch (IOException ignore) {
 // nothing we can do
 }
 }
?
 synchronized (Unmapper.class) {
 count--;
 totalSize -= size;
 totalCapacity -= cap;
 }
 }
 }
?
 //......
?
 /**
 * Invoked by sun.management.ManagementFactoryHelper to create the management
 * interface for mapped buffers.
 */
 public static JavaNioAccess.BufferPool getMappedBufferPool() {
 return new JavaNioAccess.BufferPool() {
 @Override
 public String getName() {
 return "mapped";
 }
 @Override
 public long getCount() {
 return Unmapper.count;
 }
 @Override
 public long getTotalCapacity() {
 return Unmapper.totalCapacity;
 }
 @Override
 public long getMemoryUsed() {
 return Unmapper.totalSize;
 }
 };
 }
?
 //......
}

FileChannelImpl定义了getMappedBufferPool方法,返回的是匿名JavaNioAccess.BufferPool,其相关返回实现直接使用Unmapper的对应方法;Unmapper实现了Runnable接口

小结

  • BufferPoolMXBean接口继承了PlatformManagedObject,它定义了getName、getCount、getTotalCapacity、getMemoryUsed方法
  • ManagementFactoryHelper的getBufferPoolMXBeans方法会通过createBufferPoolMXBean方法创建两个BufferPoolMXBean,然后添加到bufferPools;其中一个是DirectBufferPool,一个是MappedBufferPool;他们分别使用SharedSecrets.getJavaNioAccess().getDirectBufferPool()以及sun.nio.ch.FileChannelImpl.getMappedBufferPool()来创建
  • createBufferPoolMXBean方法接收JavaNioAccess.BufferPool参数;抽象类Buffer有个static代码块,里头创建了匿名JavaNioAccess,然后设置到了SharedSecrets中;其中匿名JavaNioAccess的getDirectBufferPool方法返回的是Bits.BUFFER_POOL;FileChannelImpl定义了getMappedBufferPool方法,返回的是匿名JavaNioAccess.BufferPool,其相关返回实现直接使用Unmapper的对应方法;Unmapper实现了Runnable接口

doc

  • Interface BufferPoolMXBean

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码