聊聊openjdk的BufferPoolMXBean
本文主要研究一下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的更多相关文章
- 聊聊 Java8 以后各个版本的新特性
作者:ZY5A59 juejin.im/post/5d5950806fb9a06b0a277412 某天在网上闲逛,突然看到有篇介绍 Java 11 新特性的文章,顿时心里一惊,毕竟我对于 Java ...
- 甲骨文严查Java授权,换openJDK要避坑
背景 外媒The Register报道,甲骨文稽查企业用户,近期开始将把过去看管较松散的Java授权加入. 甲骨文针对标准版Java(Java SE)有2种商业授权.2019年4月甲骨文宣布Java ...
- 聊聊Unity项目管理的那些事:Git-flow和Unity
0x00 前言 目前所在的团队实行敏捷开发已经有了一段时间了.敏捷开发中重要的一个话题便是如何对项目进行恰当的版本管理.项目从最初使用svn到之后的Git One Track策略再到现在的GitFlo ...
- Mono为何能跨平台?聊聊CIL(MSIL)
前言: 其实小匹夫在U3D的开发中一直对U3D的跨平台能力很好奇.到底是什么原理使得U3D可以跨平台呢?后来发现了Mono的作用,并进一步了解到了CIL的存在.所以,作为一个对Unity3D跨平台能力 ...
- fir.im Weekly - 聊聊 Google 开发者大会
中国互联网的三大错觉:索尼倒闭,诺基亚崛起,谷歌重返中国.12月8日,2016 Google 开发者大会正式发布了Google Developers 中国网站 ,包含了Android Develope ...
- 聊聊asp.net中Web Api的使用
扯淡 随着app应用的崛起,后端服务开发的也越来越多,除了很多优秀的nodejs框架之外,微软当然也会在这个方面提供更便捷的开发方式.这是微软一贯的作风,如果从开发的便捷性来说的话微软是当之无愧的老大 ...
- 没有神话,聊聊decimal的“障眼法”
0x00 前言 在上一篇文章<妥协与取舍,解构C#中的小数运算>的留言区域有很多朋友都不约而同的说道了C#中的decimal类型.事实上之前的那篇文章的立意主要在于聊聊使用二进制的计算机是 ...
- 解决Ubuntu下Firefox+OpenJDK没有Java插件的问题
如果是安装的OpenJDK,很遗憾它是没有libnpjp2.so的. 此时按照网上各种奇怪的方法都挣扎无效,但可以用icedtea插件来解决这个问题. icedtea的版本与本机安装的OpenJDK版 ...
- 聊聊 C 语言中的 sizeof 运算
聊聊 sizeof 运算 在这两次的课上,同学们已经学到了数组了.下面几节课,应该就会学习到指针.这个速度的确是很快的. 对于同学们来说,暂时应该也有些概念理解起来可能会比较的吃力. 先说一个概念叫内 ...
随机推荐
- 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 ...
- Zk搭建(Zookeeper)
第一步: 上传----解压 tar -zxvf zookeeper-3.4.5.tar.gz---- 配置zk的环境变量 ----------配置源码 vim ...
- 解决scrapy报错:ModuleNotFoundError: No module named 'win32api'
ModuleNotFoundError: No module named 'win32api' 表示win32api未安装 解决办法: 下载对应python版本的win32api,并安装. 下载地址: ...
- 城市联动 - 自动生成SQL语句
字段比较简单/ 如果有需要可以自己定制字段和排序/ 一共二级城市联动, 本人业务需要, 所以就两层, 网上关于三层的挺多, 有需要可以借鉴/ 废话不多说, 先看效果图, 代码在下面 <?php ...
- node exprss-session 和connect-mongo
let express = require('express'); let session = require('express-session'); let app = new express(); ...
- 一个简单jpa例子
package com.example.demo.entity; import javax.persistence.*; /*使用jpa注解配置映射关系*/ /*告诉jpa这是一个实体类和(数据表映射 ...
- Django--CRM-客户列表展示, 分页
一 . 客户列表展示 为了插入数据方便,我们可以用django里面的admin插入数据 创建超级用户 把语言改成中文 结果: 列表展示 展示不同字段的方式: # 有需要的可以写 def__str__( ...
- 【转】解决Maxwell发送Kafka消息数据倾斜问题
最近用Maxwell解析MySQL的Binlog,发送到Kafka进行处理,测试的时候发现一个问题,就是Kafka的Offset严重倾斜,三个partition,其中一个的offset已经快200万了 ...
- vue樣式綁定
vue的樣式可以使得class,style不僅可以綁定文本,而且可以綁定數組和對象. 使用對象{} 使用數組 綁定對象 使用computed屬性, 使用內聯樣式.
- Druid数据库连接池
一.Druid连接池的创建 package cn.zhouzhou; import java.io.IOException; import java.io.InputStream; import ja ...