本文主要研究一下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(www.gaozhuoyiqi.com 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 =www.365soke.com 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 www.gouyiflb.cn/ 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*,www.yunshenpt.com 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(www.wanmeiyuele.cn);

// 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 www.michenggw.com 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接口

聊聊openjdk的BufferPoolMXBean的更多相关文章

  1. 聊聊 Java8 以后各个版本的新特性

    作者:ZY5A59 juejin.im/post/5d5950806fb9a06b0a277412 某天在网上闲逛,突然看到有篇介绍 Java 11 新特性的文章,顿时心里一惊,毕竟我对于 Java ...

  2. 甲骨文严查Java授权,换openJDK要避坑

    背景 外媒The Register报道,甲骨文稽查企业用户,近期开始将把过去看管较松散的Java授权加入. 甲骨文针对标准版Java(Java SE)有2种商业授权.2019年4月甲骨文宣布Java ...

  3. 聊聊Unity项目管理的那些事:Git-flow和Unity

    0x00 前言 目前所在的团队实行敏捷开发已经有了一段时间了.敏捷开发中重要的一个话题便是如何对项目进行恰当的版本管理.项目从最初使用svn到之后的Git One Track策略再到现在的GitFlo ...

  4. Mono为何能跨平台?聊聊CIL(MSIL)

    前言: 其实小匹夫在U3D的开发中一直对U3D的跨平台能力很好奇.到底是什么原理使得U3D可以跨平台呢?后来发现了Mono的作用,并进一步了解到了CIL的存在.所以,作为一个对Unity3D跨平台能力 ...

  5. fir.im Weekly - 聊聊 Google 开发者大会

    中国互联网的三大错觉:索尼倒闭,诺基亚崛起,谷歌重返中国.12月8日,2016 Google 开发者大会正式发布了Google Developers 中国网站 ,包含了Android Develope ...

  6. 聊聊asp.net中Web Api的使用

    扯淡 随着app应用的崛起,后端服务开发的也越来越多,除了很多优秀的nodejs框架之外,微软当然也会在这个方面提供更便捷的开发方式.这是微软一贯的作风,如果从开发的便捷性来说的话微软是当之无愧的老大 ...

  7. 没有神话,聊聊decimal的“障眼法”

    0x00 前言 在上一篇文章<妥协与取舍,解构C#中的小数运算>的留言区域有很多朋友都不约而同的说道了C#中的decimal类型.事实上之前的那篇文章的立意主要在于聊聊使用二进制的计算机是 ...

  8. 解决Ubuntu下Firefox+OpenJDK没有Java插件的问题

    如果是安装的OpenJDK,很遗憾它是没有libnpjp2.so的. 此时按照网上各种奇怪的方法都挣扎无效,但可以用icedtea插件来解决这个问题. icedtea的版本与本机安装的OpenJDK版 ...

  9. 聊聊 C 语言中的 sizeof 运算

    聊聊 sizeof 运算 在这两次的课上,同学们已经学到了数组了.下面几节课,应该就会学习到指针.这个速度的确是很快的. 对于同学们来说,暂时应该也有些概念理解起来可能会比较的吃力. 先说一个概念叫内 ...

随机推荐

  1. Git push提交时报错Permission denied(publickey)...Please make sure you have the correct access rights and the repository exists.

    一.git push origin master 时出错 错误信息为: Permission denied(publickey). fatal: Could not read from remote ...

  2. Zk搭建(Zookeeper)

      第一步: 上传----解压   tar -zxvf zookeeper-3.4.5.tar.gz----                配置zk的环境变量  ----------配置源码 vim ...

  3. 解决scrapy报错:ModuleNotFoundError: No module named 'win32api'

    ModuleNotFoundError: No module named 'win32api' 表示win32api未安装 解决办法: 下载对应python版本的win32api,并安装. 下载地址: ...

  4. 城市联动 - 自动生成SQL语句

    字段比较简单/  如果有需要可以自己定制字段和排序/ 一共二级城市联动, 本人业务需要, 所以就两层, 网上关于三层的挺多, 有需要可以借鉴/ 废话不多说, 先看效果图, 代码在下面 <?php ...

  5. node exprss-session 和connect-mongo

    let express = require('express'); let session = require('express-session'); let app = new express(); ...

  6. 一个简单jpa例子

    package com.example.demo.entity; import javax.persistence.*; /*使用jpa注解配置映射关系*/ /*告诉jpa这是一个实体类和(数据表映射 ...

  7. Django--CRM-客户列表展示, 分页

    一 . 客户列表展示 为了插入数据方便,我们可以用django里面的admin插入数据 创建超级用户 把语言改成中文 结果: 列表展示 展示不同字段的方式: # 有需要的可以写 def__str__( ...

  8. 【转】解决Maxwell发送Kafka消息数据倾斜问题

    最近用Maxwell解析MySQL的Binlog,发送到Kafka进行处理,测试的时候发现一个问题,就是Kafka的Offset严重倾斜,三个partition,其中一个的offset已经快200万了 ...

  9. vue樣式綁定

    vue的樣式可以使得class,style不僅可以綁定文本,而且可以綁定數組和對象. 使用對象{} 使用數組 綁定對象 使用computed屬性, 使用內聯樣式.

  10. Druid数据库连接池

    一.Druid连接池的创建 package cn.zhouzhou; import java.io.IOException; import java.io.InputStream; import ja ...