本文主要研究一下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. atcoderI - Coins ( 概率DP)

    I - Coins Time Limit: 2 sec / Memory Limit: 1024 MB Score : 100100 points Problem Statement Let NN b ...

  2. YCSB报": No such file or directory"异常

    异常信息如下: 文件路径.权限都没有问题. 上网遍寻无果,安装流程与官网一致,开始怀疑是环境问题,后来用别人能用的YCSB复制到本地,却能正常运行. 后来修改了ycsb文件,加了个空格,保存退出,再运 ...

  3. rest-framework序列化

    快速实例 Quickstart 序列化 开篇介绍: ---- 一切皆是资源,操作只是请求方式 ----book表增删改查 /books/ books /books/add/ addbook /book ...

  4. Django的模板语言

      Django模板系统 官方文档 常用语法 只需要记两种特殊符号: {{  }}和 {% %} 变量相关的用{{}},逻辑相关的用{%%}. 变量 {{ 变量名 }} 变量名由字母数字和下划线组成. ...

  5. ssh无密码登录多台机器,并让所有远程机执行相同命令

    问题集锦 其实标题的内容就是很常见的集群操作,当有一个脚本或者一个命令需要很多个机器同时(或者说接近同时)执行时,就涉及到几个问题: 怎么通知每个主机? 每个主机收到通知后,怎么让主机执行命令? 怎么 ...

  6. spring datasource jdbc 密码 加解密

    spring datasource 密码加密后运行时解密的解决办法 - 一号门-程序员的工作,程序员的生活(java,python,delphi实战)http://www.yihaomen.com/a ...

  7. sql学习内容记录

    1.left函数 left(字段,长度):获取指定字段左侧的数据,类似substring函数 2.union / union all 将多个记录合并成一个完整的数据集 3.insert into se ...

  8. SSH上传/下载本地文件到linux服务器

    在linux下一般用scp这个命令来通过ssh传输文件. 1.从服务器上下载文件 scp username@servername:/path/filename /var/www/local_dir(本 ...

  9. js刷新界面前事件onbeforeunload

    这个方法的作用是防止填写信息时不小心按了刷新(F5,刷新界面,返回). 目前能实现这个需求的只有这个方法. 具体代码如下: 1.首先在body添加 onbeforeunload 这个事件 <bo ...

  10. Oracle 用户管理与权限分配

    用户管理是系统管理员最基本的任务之一,用户想要连接数据库并且使用相应的系统资源就必须是系统的合法用户且具有对应的权限. 1 创建用户 default tablespace default_tables ...