jvm 堆外内存_Java Nio 之直接内存

e224838527b2d6ef6f83202483e93f7e.png

开始奋斗

堆外内存和堆上内存

首先来讲一下什么是堆上内存,在java 中我们经常会编写类似下面一段代码

代码清单1-1

public class HeapByteBufferDemo { public static void main(String[] args) { Demo demo = new Demo();//1 demo.print(); }}class Demo{ void print() { System.out.println("i am a demo"); }}

1 处 使用new 关键字 去创建Demo对象,具体分为三步:

  • 在jvm 运行时数据区中的堆上申请一块内存空间
  • 初始化实例对象
  • 把引用demo 指向分配的内存空间

此时 demo 引用指向的是堆上的一块内存空间,它由jvm管理的,同样也是gc 的主要工作区域。默认我们使用new 关键字,以及newInstance 都是在堆上申请内存。使用堆上的内存在多数情况下都是大家的首选,但是有些情况下我们使用堆外的内存就比较合适,什么是堆外内存呢,就是不被jvm 所管理的其他内存,简称堆外内存。

堆外内存也称直接内存,下面来说下使用直接内存的两个好处:

  • 直接内存是在堆外,申请过多不会引起gc;例:申请一块堆外空间,当内存池去使用,netty 就是这种机制,有兴趣的同志可以去研究下,这也是我这个专栏将要涉及的地方。
  • 在我们写数据的时候,若数据在堆上,则需要从堆上拷贝到堆外,操作系统才可以去操作这个拷贝的数据;若数据在堆外,就少了一次从堆上拷贝到堆外这个阶段了,节省的时间是非常明显的。大家可能比较纳闷为啥我们的操作系统属于内核态 在ring0级别按理说可以访问所有内存,为啥不直接操作堆上的数据,因为Java 有gc,gc 可能不会回收要被写的数据,但是可能会移动它(把已用内存压缩在一边,清除内存碎片),操作系统是通过内存地址去操作内存的,内存地址变了,这些写到文件或者网络里的数据可能并不是我们想要写的数据,也有可能产生很多未知的错误。

如何使用直接内存(这里使用上节的小例子)

代码清单2-1

/** * @author lzq */public class DirectBufferDemo { public static void main(String[] args) { ByteBuffer demoDirectByteBuffer = ByteBuffer.allocateDirect(8);//A printBufferProperties("write to demoDirectByteBuffer before 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值