zoukankan      html  css  js  c++  java
  • 堆内存和堆外内存(又名直接内存)比较

    https://blog.csdn.net/lidengchun/article/details/75085680

          堆内存根据生命周期进行分而治之,分区之后可以提高JVM垃圾收集的效率,更好地回收为了更好地分配。

    如果在堆中无法分配内存,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常。


    http://blog.csdn.net/qq_17612199/article/details/52316719

             HeapByteBuffer与DirectByteBuffer,在原理上,前者可以看出分配的buffer是在heap区域的,其实真正flush到远程的时候会先拷贝得到直接内存,再做下一步操作(考虑细节还会到OS级别的内核区直接内存),其实发送静态文件最快速的方法是通过OS级别的send_file,只会经过OS一个内核拷贝,而不会来回拷贝;在NIO的框架下,很多框架会采用DirectByteBuffer来操作,这样分配的内存不再是在Java heap上,而是在C heap上,经过性能测试,可以得到非常快速的网络交互,在大量的网络交互下,一般速度会比HeapByteBuffer要快速好几倍。

    直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域,但是这部分内存也被频繁地使用,而且也可能导致OutOfMemoryError 异常出现,所以我们放到这里一起讲解。 
    在JDK 1.4 中新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区(Buffer)的I/O 方式,它可以使用Native 函数库直接分配堆外内存,然后通过一个存储在Java 堆里面的DirectByteBuffer 对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在Java 堆和Native 堆中来回复制数据。

    import sun.nio.ch.DirectBuffer; 
    import java.nio.ByteBuffer;
     
    public class Main {
     
        public static void main(String[] args) throws InterruptedException {
            System.out.println("Hello World!");
            ByteBuffer bb = ByteBuffer.allocateDirect(1024 * 1024 * 128);
            Thread.sleep(10000);
            ((DirectBuffer)bb).cleaner().clean();
            Thread.sleep(10000);
        }
    }

    可以在任务管理器那观察变化

    堆外内存的优点和缺点

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

     1 减少了垃圾回收的工作,因为垃圾回收会暂停其他的工作(可能使用多线程或者时间片的方式,根本感觉不到) 
     2 加快了复制的速度。因为堆内在flush到远程时,会先复制到直接内存(非堆内存),然后在发送;而堆外内存相当于省略掉了这个工作。 

    缺点: 
      1 堆外内存难以控制,如果内存泄漏,那么很难排查 
      2 堆外内存相对来说,不适合存储很复杂的对象。一般简单的对象或者扁平化的比较适合。

    优点:

           1.  减少GC时间

           2.  进程间可以共享,减少虚拟机间的复制

    _______________________________________________________________________________________________

    为什么引进非Java堆?

    1 Java如果和外界通讯,把Java 堆中的内容传输到外界,则需要把Java堆复制到非Java堆,如果使用native堆,则避免了内容在Java堆和非Java堆之间的copy.

    在什么场景下使用非Java堆?

    1 非Java堆的回收不受java  gc的影响,一般需要手工进行回收。如果大量的使用非Java堆,则丢失了Java 自动垃圾回收的特点。

    一般使用非Java堆进行和外界通讯,并且做为缓存使用。如DirectByteBuffer。

  • 相关阅读:
    mac与ip为什么同时存在
    tcp四次挥手
    tcp三次握手
    GET与POST的区别
    Servlet.service() for servlet [jsp] in context ....错误
    c3p0连接数据库时注意事项
    finalize()及垃圾回收
    composer 安装新包失败的原因之一
    如何使用优酷开放平台获取视频播放列表
    php解析优酷网上的视频资源去广告
  • 原文地址:https://www.cnblogs.com/kelelipeng/p/15640177.html
Copyright © 2011-2022 走看看