JVM-直接内存(Direct Memory)
上文:对象实例化与内存布局(深入)直接内存(Direct Memory)直接内存是Java堆之外的,直接向系统申请的内存空间,所以直接内存不是虚拟机的一部分,也不是《Java虚拟机...
目录
直接内存(Direct Memory)
直接内存是Java堆之外的,直接向系统申请的内存空间,所以直接内存不是虚拟机的一部分,也不是《Java虚拟机规范》中定义的内存区域,也有可能导致OOM。
非直接缓存区
在jdk1.4之前,java的对象与系统之间的交互如下图,先从JVM需要从用户态切换到内核态时,这样的话读取或写入一份数据需要经历四个步骤:jvm切换到内核态缓冲区读取->操作系统将数据拷贝用户缓冲区-->-再次切换到内核态并将用户缓存区数据拷贝进来->将内核态缓冲区写入socket buffer(cpu参与两次)
直接缓存区
直接内存也称直接缓存区,主要是解决一个java读取慢的问题,jdk1.4以后jvm 引入了NIO在操作系统划出了一块直接的缓存区可以直接被java访问。就是所称的零拷贝。
用户->内核态缓冲区(cpu不参与)
零拷贝文章:什么是零拷贝(Zero-copy)?
代码实现
非直接缓冲区
/**
* @author: csh
* @Date: 2021/5/8 18:49
* @Description:非直接缓存冲(堆内存)
*/
public class ByteBufferTest {
public static void main(String[] args) {
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1024*1024*1024);
System.out.println("开始分配内存");
Scanner scanner = new Scanner(System.in);
scanner.next();
System.out.println("直接内存开始释放");
byteBuffer=null;
System.gc();
scanner.next();
}
}
释放前
释放后
模拟直接内存溢出
/**
* @author: csh
* @Date: 2021/5/13 18:37
* @Description:OOM 模拟直接内存溢出
*
* Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory
*/
public class BufferTest2 {
private static final int BUFFER =1024 * 1024 * 20;
public static void main(String[] args) {
ArrayList<ByteBuffer> list = new ArrayList <>();
int count = 0;
try {
while (true){
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BUFFER);
list.add(byteBuffer);
Thread.sleep(100);
}
}catch (Exception e){
System.out.println("总共打印");
e.printStackTrace();
}
}
}
结果
Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory
at java.nio.Bits.reserveMemory(Bits.java:694)
at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:123)
at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:311)
at com.memory.BufferTest2.main(BufferTest2.java:22)
最后
不管是直接内存还是传统的内存,都有利有弊,比如直接内存可以尽大限度的拓展内存空间,但是一但发生oom那排查起来非常麻烦,因为这块控制是非常难的,并且只有当full gc才会被回收,当然也是可以通过:通过-XX:MaxDirectMemorySize来指定最大的堆外内存大小。直接内存的写入速度没有
参考文章 https://www.cnblogs.com/yy3b2007com/archive/2017/07/31/7262453.html
https://zh.wikipedia.org/w/index.php?title=%E7%9B%B4%E6%8E%A5%E8%A8%98%E6%86%B6%E9%AB%94%E5%AD%98%E5%8F%96&useFormat=mobile&variant=zh-sg
https://my.oschina.net/newchaos/blog/4873863
https://developer.aliyun.com/article/763697
https://zhuanlan.zhihu.com/p/161939673
参考书籍
《深入理解Java虚拟机》 –周志明
往期推荐
spring整合各种中间件(RocketMQ、kafka、RabbitMQ、ActiveMQ、ZeroMQ)-ZeroMQ
spring整合中间件(RocketMQ、kafka、RabbitMQ、ActiveMQ、ZeroMQ)ActiveMQ
更多推荐
所有评论(0)