java allocatedirect_Java中的Heap Buffer与Direct Buffer
在使用Java NIO时,会经常和ByteBuffer打交道(吐槽下,每次手动flip切换读写模式太不友好)。在空Buffer创建时,有两种方式:
ByteBuffer.allocateDirect(capacity)
ByteBuffer.allocate(capacity)
那么这两种Buffer的分配又有什么不一样呢?
Heap Buffer
字面意思,在java heap上分配的内存。此块内存区域受JVM管理,GC负责回收。使用时无需担心Heap Buffer的回收问题。
Direct Buffer
堆外内存(说非堆不太准确,毕竟非堆区域不止这一块),时分配在C Heap上的Buffer,由于不属于JVM HEAP,管理/监控起来会比较困难,但也会被GC回收。DirectByteBuffer 自身是(Java)堆内的,它背后真正承载数据的buffer是在(Java)堆外——native memory中的。这是 malloc() 分配出来的内存,是用户态的。
那么为什么有了Heap Buffer还需要Direct Buffer呢?
在JVM的垃圾回收器里,除了CMS,都是需要移动对象的;如果要把一个Java里的 byte[] 对象的引用传给native代码,让native代码直接访问数组的内容的话,就必须要保证native代码在访问的时候这个 byte[] 对象不能被移动,也就是要被“pin”(钉)住。
于是就出现了Direct Buffer,Direct Buffer是在C Heap中分配的内存,不像JVM堆内存是逻辑的,虽然也会被GC管理,但他是通过PhantomReference来达到的,正常的young gc或者mark and compact的时候不会在内存里移动。例如使用在传输数据时(磁盘IO传输和Socket传输都属于fd),如果传入HeapByteBuffer,首先会把HeapByteBuffer 背后的 byte[] 的内容拷贝到一个 DirectByteBuffer,然后再发送DirectByteBuffer中的数据。如果直接使用DirectByteBuffer的话,就会少了一次HeapByteBuffer->DirectByteBuffer的拷贝。
但是使用DirectByteBuffer也是有代价的,DirectByteBuffer比HeapByteBuffer的创建开销更大,所以如果要使用DirectByteBuffer的话最好还是复用,避免过多的创建。
堆外内存的监控
堆外内存不像堆内内存监控那么简单,不能直接看堆信息,但可以通过程序获取,或者通过一些监控工具来查看
jconsole
jvisualvm
注:需要安装VisualVM-BufferMonitor和VisualVM-MBeans插件
Java
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(4096);
RandomAccessFile rw = new RandomAccessFile(new File("/Users/jiangxin/Desktop/111"), "rw");
MappedByteBuffer map = rw.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, 4097);
//打印堆外
List pools = ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class);
for (BufferPoolMXBean pool : pools) {
System.out.println(pool.getName());
System.out.println(pool.getCount());
System.out.println("memory used " + pool.getMemoryUsed());
System.out.println("total capacity" + pool.getTotalCapacity());
System.out.println();
}
direct
1
memory used 4096
total capacity4096
mapped
1
memory used 4097
total capacity4097
java allocatedirect_Java中的Heap Buffer与Direct Buffer相关推荐
- JAVA NIO之Direct Buffer 与 Heap Buffer的区别?
2019独角兽企业重金招聘Python工程师标准>>> 个人总结 Direct Buffer vs. Heap Buffer 1. 劣势:创建和释放Direct Buffer的代 ...
- 【Kafka】kafka OutOfMemoryError: Direct buffer memory Java heap space
1.背景 做实验:[Kafka]Kafka如何开启SSL 控制台消费与生产 代码消费与生产 的时候,因为机器太卡导致内存溢出 java.lang.OutOfMemoryError: Direct bu ...
- Java中内存中的Heap、Stack与程序运行的关系
堆和栈的内存管理 栈的内存管理是顺序分配的,而且定长,不存在内存回收问题:而堆 则是随机分配内存,不定长度,存在内存分配和回收的问题: 堆内存和栈内存的区别可以用如下的比喻来看出:使用堆内存就象是自己 ...
- java 缓冲区中的数据存入缓冲区中_java8中NIO缓冲区(Buffer)的数据存储详解|chu...
java8新特性NIO缓冲区(Buffer)的数据存储. ByteBuffer,CharBuffer,ShortBuffer,IntBuffer,LongBuffer,FloatBuffer, Dou ...
- Java NIO中的Buffer
简介 Buffer缓冲区,首先要弄明白的是,缓冲区是怎样一个概念.它其实是缓存的一种,我们常说的缓存,包括保存在硬盘上的浏览器缓存,保存在内存中的缓存(比如Redis.memcached).Buffe ...
- Java开发中出现OOM的常见原因有哪些?
当JVM内存严重不足时,就会抛出java.lang.OutOfMemoryError错误.本文总结了常见的OOM原因及其解决方法,如下图所示.如有遗漏或错误,欢迎补充指正. 1.Java heap s ...
- Java 并发编程解析 | 如何正确理解Java领域中的内存模型,主要是解决了什么问题?
写在开头 这些年,随着CPU.内存.I/O 设备都在不断迭代,不断朝着更快的方向努力.在这个快速发展的过程中,有一个核心矛盾一直存在,就是这三者的速度差异.CPU 和内存的速度差异可以形象地描述为:C ...
- java葵花宝典中的宝典!
葵花宝典之java 一:面向对象的特征有哪些方面 1.抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只是选择其中的一部分,暂时 ...
- Java 并发编程解析 , 如何正确理解Java领域中的内存模型
这些年,随着CPU.内存.I/O 设备都在不断迭代,不断朝着更快的方向努力.在这个快速发展的过程中,有一个核心矛盾一直存在,就是这三者的速度差异.CPU 和内存的速度差异可以形象地描述为:CPU 是天 ...
最新文章
- 加载部分神经网络预训练参数后改写网络的方法
- eureka心跳_Eureka工作原理及心跳机制
- python程序只能使用源代码进行运行吗-python在运行时更改源代码
- 模糊神经网络PID控制的一个例子
- 常见RAID的各级别的特性简介(RAID0、1、5、6、10)
- caffe源码解析—image_data_layer层
- 2分钟学会ajax 入门ajax必备
- Android学习笔记----Java中的字符串比较
- 最近对焦距离与最大放大倍率
- python 柱状图上显示字体_Python爬取百部电影数据,我发现了这个惊人真相!
- html大小和浏览器可视区域一样吗,浏览器窗口可视区域大小和网页尺寸和网页卷去的距离与偏移量...
- c++核心编程第一部分讲义_java并发编程实战-第一部分总结
- C++虚函数调用的反汇编解析
- R语言期末试题-重庆工商大学-统计学课程
- IMU惯性测量单元是什么?
- [论文阅读] Universal Weighting Metric Learning for Cross-Modal Matching
- 三星a5009Android6.0,三星A5009 6.0 root教程及获取6.0的root权限
- rosetta_ddg 使用-rosetta 2020版
- 【破事氵】在Linux环境中让程序在后台运行
- 简单介绍下微信群大全500人大群及免费微信互投群万人群