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。

  • 相关阅读:
    一些你可能用到的代码
    iOS 键盘下去的方法
    iOS设计模式汇总
    随笔
    Spring cloud config 分布式配置中心 (三) 总结
    Spring cloud config 分布式配置中心(二) 客户端
    Spring cloud config 分布式配置中心(一) 服务端
    jdbcUrl is required with driverClassName spring boot 2.0版本
    JpaRepository接口找不到 spring boot 项目
    解决IntelliJ “Initialization failed for 'https://start.spring.io'
  • 原文地址:https://www.cnblogs.com/kelelipeng/p/15640177.html
Copyright © 2011-2022 走看看