对于有Java开发经验的朋友都知道,Java中不需要手动的申请和释放内存,JVM会自动进行垃圾回收;而使用的内存是由JVM控制的。

那么,什么时机会进行垃圾回收,如何避免过度频繁的垃圾回收?如果JVM给的内存不够用,怎么办?

此时,堆外内存登场!利用堆外内存,不仅可以随意操控内存,还能提高网络交互的速度。

背景1:JVM内存的分配

对于JVM的内存规则,应该是老生常谈的东西了,这里我就简单的说下:

新生代:一般来说新创建的对象都分配在这里。

年老代:经过几次垃圾回收,新生代的对象就会放在年老代里面。年老代中的对象保存的时间更久。

永久代:这里面存放的是class相关的信息,一般是不会进行垃圾回收的。

背景2:JVM垃圾回收

由于JVM会替我们执行垃圾回收,因此开发者根本不需要关心对象的释放。但是如果不了解其中的原委,很容易内存泄漏,只能两眼望天了!

垃圾回收,大致可以分为下面几种:

Minor GC:当新创建对象,内存空间不够的时候,就会执行这个垃圾回收。由于执行最频繁,因此一般采用复制回收机制。

Major GC:清理年老代的内存,这里一般采用的是标记清除+标记整理机制。

Full GC:有的说与Major GC差不多,有的说相当于执行minor+major回收,那么我们暂且可以认为Full GC就是全面的垃圾回收吧。

堆外内存?

堆外内存,其实就是不受JVM控制的内存。相比于堆内内存有几个优势:

1 减少了垃圾回收的工作,因为垃圾回收会暂停其他的工作(可能使用多线程或者时间片的方式,根本感觉不到)

2 加快了复制的速度。因为堆内在flush到远程时,会先复制到直接内存(非堆内存),然后在发送;而堆外内存相当于省略掉了这个工作。

而福之祸所依,自然也有不好的一面:

1 堆外内存难以控制,如果内存泄漏,那么很难排查

2 堆外内存相对来说,不适合存储很复杂的对象。一般简单的对象或者扁平化的比较适合。

堆外内存可以通过java.nio的ByteBuffer来创建,调用allocateDirect方法申请即可。参考API地址

至于怎么用,读读API文档就知道啦~

另外,默认的情况下堆外内存是有一定的限制的,好像是64M吧....

可以通过设置-XX:MaxDirectMemorySize=10M控制堆外内存的大小:

堆外内存的垃圾回收

堆外内存,既然可以无限使用,那么会不会用爆内存呢?这个是很有可能的...所以堆外内存的垃圾回收也很重要。

由于堆外内存并不直接控制于JVM,因此只能等到full GC的时候才能垃圾回收!

Full GC,一般发生在年老代垃圾回收以及调用System.gc的时候,这样肯定不能满足我们的需求!况且很多线上环境的JVM参数有-XX:+DisableExplicitGC,导致了System.gc()等于一个空函数,根本不会触发FGC,这一点在使用Netty框架时需要注意是否会出问题。

于是度娘帮助解决了这个问题,网上有朋友十分聪明的利用内部实现接口,反向获取到了一个clear方法!

package xing.test;

import java.nio.ByteBuffer;

import sun.nio.ch.DirectBuffer;

public class NonHeapTest {

public static void clean(final ByteBuffer byteBuffer) {

if (byteBuffer.isDirect()) {

((DirectBuffer)byteBuffer).cleaner().clean();

}

}

public static void sleep(long i) {

try {

Thread.sleep(i);

}catch(Exception e) {

/*skip*/

}

}

public static void main(String []args) throws Exception {

ByteBuffer buffer = ByteBuffer.allocateDirect(1024 * 1024 * 200);

System.out.println("start");

sleep(5000);

clean(buffer);//执行垃圾回收

// System.gc();//执行Full gc进行垃圾回收

System.out.println("end");

sleep(5000);

}

}

这样就能手动的控制回收堆外内存了!其中sun.nio其实是java.nio的内部实现。所以你可能不能通过eclipse的自动排错找到这个包,直接复制

import sun.nio.ch.DirectBuffer;

就行。

由于本文整理与网络各种资料,有些不对的地方还请指正,共同探讨!

java nio 堆外内存_Java堆外内存之突破JVM枷锁相关推荐

  1. java保证一段代码枷锁_Java堆外内存之突破JVM枷锁

    对于有Java开发经验的朋友都知道,Java中不需要手动的申请和释放内存,JVM会自动进行垃圾回收:而使用的内存是由JVM控制的. 那么,什么时机会进行垃圾回收,如何避免过度频繁的垃圾回收?如果JVM ...

  2. java堆内存和堆外内存_Java堆空间,本机堆和内存问题

    java堆内存和堆外内存 最近,我正在和一个朋友讨论为什么Java进程使用的内存比启动Java进程时设置的最大堆多. 代码创建的所有Java对象都是在Java堆空间内创建的,其大小由-Xmx选项定义. ...

  3. java9 堆外内存_java堆外内存泄漏排查

    当考虑Java中的内存泄漏时,我们通常会考虑Java堆泄漏,即在堆中分配的对象没有被垃圾收集.这是我在处理一台服务器内存泄漏时的想法,但我即将经历的远超出我的想象. 症状:运行Vertx应用程序(没有 ...

  4. java堆内存_java堆内存详解

    http://www.importnew.com/14630.html java堆的特点 <深入理解java虚拟机>是什么描述java堆的 Java堆(Java Heap)是java虚拟机 ...

  5. java中堆栈内存_Java堆空间与堆栈– Java中的内存分配

    java中堆栈内存 Sometime back I wrote a couple of posts about Java Garbage Collection and Java is Pass by ...

  6. java中的堆空间增加_Java堆内存的10个要点

    当我开始学习Java编程时,我不知道什么是堆内存或堆空间,我甚至不知道当对象创建时,它们被放在了哪里.当我开始正式写一些程序后,我会经常遇到java.lang.outOfMemoryError的报错, ...

  7. java 堆的使用_Java堆

    Java堆的基本概念 Java 堆是虚拟机所管理的内存中最大的一块,是被所有线程共享的一块内存区域,在虚拟机启动时创建.此内存区域的唯一作用就是存放对象实例,几乎所有的对象实例都是在这里分配的(不绝对 ...

  8. java 常量池 和 堆 的关系_Java堆、栈和常量池以及相关String的详细讲解(经典中的经典)...

    博客分类: Java综合 一:在JAVA中,有六个不同的地方可以存储数据: 1. 寄存器(register). 这是最快的存储区,因为它位于不同于其他存储区的地方--处理器内部.但是寄存器的数量极其有 ...

  9. java 堆转储快照_Java堆转储:您可以完成任务吗?

    java 堆转储快照 如果您像我一样对Java性能充满热情,那么堆转储分析对您来说应该不是一个谜. 如果是这样,那么好消息是您将有机会增加您的Java故障排除技能和JVM知识. JVM现在已经发展到这 ...

最新文章

  1. 【Python line_profiler memory_profiler】分析每一行代码的耗时及内存占用情况
  2. c语言实现4x4随机字母,求用C++编写一个4x4矩阵运算类(元素float),实现转置和相乘,具体见补充,在线等!谢谢啦~...
  3. centos安装g++
  4. 项目: 用C语言写一个音乐播放器
  5. 【c语言 gcc9.1.0环境下编译报错】error: ‘true’ undeclared (first use in this function)
  6. vue 出现Elements in iteration expect to have 'v-bind:key' directives
  7. 计算机无法用telnet,telnet不是内部或外部命令解决办法 Windows10开启Telnet功能方法...
  8. css的3d注意事项
  9. mysql 8创建远程访问用户以及连接mysql速度慢的解决方法
  10. 使用RemotePotato0从普通用户提升至域管理员
  11. chrome 历史版本和chrome webDriver历史版本
  12. CAD:计算三角形的外接圆圆心
  13. 复制xml导致乱码问题解决。
  14. MarkDown在线编辑器(支持公众号知乎)
  15. 史上最详细mac安装Qt教程
  16. 英语笔记(单词来自Shiro文档)02
  17. 跨平台web app教育设备的一些设计标准
  18. NFC手机手环脱机模拟加密门禁卡
  19. selenium学习——问卷星(可控比例)
  20. Ajax开发小结慎用AJAX框架

热门文章

  1. Centos7把一个文件复制到另外一台服务器上的scp命令
  2. 【已解决】linux redhat 6 如何打开防火墙中的某个端口?例如:5900端口
  3. AXI quad SPI没有输出
  4. 移除添加的文件_文件压缩教程-文件批量压缩
  5. ios设置tabbar背景颜色_WooCommerce微信小程序2.9.3版本发布 后台设置主题色 底栏装修定制...
  6. excel中match函数_Excel函数轻松学02:详解Excel函数中的数据类型
  7. 启明云端分享|AIOT+智慧屏解决方案,用色彩渲染智慧生活
  8. ipad显示ping连接服务器失败,ipad突然连不上网如何修复
  9. mysql 查询数据 程序_MySQL 查询数据
  10. linux安装教程 ce,docker CE安装教程