精华内容
下载资源
问答
  • 直接缓冲区:通过allocate()方法分配缓冲区,将缓冲区建立在jvm内存中。 直接缓冲区:通过allocateDirect() 方法分配直接缓冲区,将缓冲区建立在物理内存中。可以提高效率。 字节缓冲区要么是直接的要么是非直接...

    非直接缓冲区:通过allocate()方法分配缓冲区,将缓冲区建立在jvm内存中。
    直接缓冲区:通过allocateDirect() 方法分配直接缓冲区,将缓冲区建立在物理内存中。可以提高效率。
    这里写图片描述

    这里写图片描述

    • 字节缓冲区要么是直接的要么是非直接的。如果是直接缓冲区,则java虚拟机会尽最大努力直接在此缓冲区上执行本机IO操作。也就是说,在每次调用基础操作系统的一个本机IO操作之前(或之后)虚拟机都会尽量避免将缓冲区的内容复制到中间缓冲区中(或从中间缓冲区中复制内容)。

    • 直接直接缓冲区可以通过调用此类的allocateDirect()工厂方法来创建。此方法返回的缓冲区进行分配和取消分配所需要的成本通常高于非直接缓冲区。直接缓冲区的内容可以驻留在常规的垃圾回收堆中,此外,他们对应用程序的内存需求量造成的影响可能并不明显。所以,建议将缓冲区主要分配在那些容易受基础系统的本机IO操作影响的大型、持久的缓冲区。一般情况下,最好仅在直接缓冲区能在程序性能方面带来明显好处时分配它们。

    • 直接缓冲区还可以通过FileChannel的map()方法将文件区域直接映射到内存中来创建。该方法返回MappedByteBuffer。java平台的实现有助于通过JNI从本机代码创建直接字节缓冲区。如果以上这些缓冲区中的某个缓冲区实例指的是不可访问的内存区域,则试图访问该区域不会改变该区域的内容,并且将会在访问期间或稍后某个时间抛出不确定的异常

    • 字节缓冲区是直接缓冲区还是非直接缓冲区可以通过调用其isDirect()方法来确定。提供此方法是为了能够在性能关键型代码中执行显式缓冲区管理。

    展开全文
  • 直接与非直接缓冲区   字节缓冲区跟其他缓冲区类型最明显的不同在于,它们可以成为通道所执行的 I/O 的源头和/或目标。其实发现通道只接收ByteBuffer作为参数这个将Channel的时候会发现。 类型 优点 缺点 ...

    直接与非直接缓冲区

      字节缓冲区跟其他缓冲区类型最明显的不同在于,它们可以成为通道所执行的 I/O 的源头和/或目标。其实发现通道只接收ByteBuffer作为参数这个将Channel的时候会发现。

    类型优点缺点
    直接缓冲区在虚拟机内存外,开辟的内存,
    IO操作直接进行,没有再次复制
    创建和销毁开销大
    非直接缓冲区在虚拟机内存中创建,易回收但占用虚拟机内存开销,
    处理中有复制过程。

    直接缓冲区

      直接缓存区是在虚拟机内存外,开辟的内存,IO操作直接进行,不再对其进行复制,但创建和销毁开销大。

    在这里插入图片描述

    非直接缓冲区

      非直接缓存区在虚拟机内存中创建,易回收,但占用虚拟机内存开销,处理中有复制过程。

    在这里插入图片描述

    直接和非直接缓冲区解释

      操作系统在内存区域中进行I/O操作,这些内存区域,就操作系统方面而言,是相连的字节序列。所以,只有字节缓冲区有资格参与I/O操作。操作系统会直接存取进程——在本例中是JVM进程的内存空间,以传输数据。这也意味着I/O操作的目标内存区域必须是连续的字节序列。在JVM中,字节数组可能不会在内存中连续存储,或者无用存储单元收集可能随时对其进行移动。在Java中,数组是对象,而数据存储在对象中的方式在不同的JVM实现中都各有不同。出于这一原因,引入了直接缓冲区的概念。

      直接字节缓冲区通常是I/O操作最好的选择。在设计方面,它们支持JVM可用的最高效I/O机制。非直接字节缓冲区可以被传递给通道,但是这样可能导致性能损耗。通常非直接缓冲不可能成为一个本地I/O操作的目标。如果向一个通道中传递一个非直接ByteBuffer对象用于写入,通道可能会在每次调用中隐含地进行下面的操作:

    1. 创建一个临时的直接ByteBuffer对象。
    2. 将非直接缓冲区的内容复制到临时缓冲中。
    3. 使用临时缓冲区执行低层次I/O操作。
    4. 临时缓冲区对象离开作用域,并最终成为被回收的无用数据。

      直接缓冲区是I/O的最佳选择,但可能比创建非直接缓冲区要花费更高的成本。直接缓冲区使用的内存是通过调用本地操作系统方面的代码分配的,绕过了标准JVM堆栈。建立和销毁直接缓冲区会明显比具有堆栈的缓冲区更加破费,这取决于主操作系统以及JVM实现。直接缓冲区的内存区域不受无用存储单元收集支配,因为它们位于标准JVM堆栈之外。

      直接ByteBuffer是通过调用ByteBuffer.allocateDirect()函数产生的,注意用一个wrap()函数所创建的被包装的缓冲区总是非直接的。

    public abstract class ByteBuffer extends Buffer implements Comparable {
        // This is a partial API listing
        public static ByteBuffer allocate(int capacity)
        public static ByteBuffer allocateDirect(int capacity)
        public abstract boolean isDirect();
    }
    

    使用直接缓冲区有两种方式:

    1. 缓冲区创建的时候分配的是直接缓冲区
    2. 在FileChannel上调用map()方法,将文件直接映射到内存中创建
    展开全文
  • 创建堆缓冲区与直接缓冲区 allocateDirect(int capacity): 分配新的直接字节缓冲区.新的缓冲区的位置将为0,其界限为其容量,其标记是不确定的.无论它是否具有底层实现数组,其标记都是不确定的. allocate(int capacity...

    创建堆缓冲区与直接缓冲区

    allocateDirect(int capacity): 分配新的直接字节缓冲区.新的缓冲区的位置将为0,其界限为其容量,其标记是不确定的.无论它是否具有底层实现数组,其标记都是不确定的.

    allocate(int capacity): 分配一个新的非直接字节缓冲区.新缓冲区的位置为0,其界限为其容量,其标记是不确定的.它将具有一个底层实现数组,且其数组偏移量将为0.

    如果字节缓冲区为直接字节缓冲区,则JVM会尽量在直接字节缓冲区上执行本机I/O操作,也就是直接对内核空间进行访问,以提高运行效率.提高运行效率的原理就是在每次调用基于操作系统地I/O操作之前或之后,JVM都会尽量避免将缓冲区的内容复制到中间缓冲区中,或者从中间缓冲区中复制内容,这样就节省了一个步骤.

    通过allocateDirect()返回的缓冲区进行内存的分配和释放所需的时间成本通常高于非直接缓冲区.直接缓冲区操作的数据不在JVM堆中,而是在内核空间中,根据这个结构可以分析出,直接缓冲区善于保存那些易受操作系统本机I/O操作影响的大量、长时间保存到的数据。

    使用allocateDirect()方法创建出来的缓冲区类型为DirectByteBuffer,使用allocate()方法创建出来的缓冲区类型为HeapByteBuffer.

    使用allocateDirect()方法创建ByteBuffer缓冲区时,capacity指的是字节的个数,而创建IntBuffer缓冲区时,capacity指的是int值得数目,如果要转换成字节,则capacity要乘以4,来算出占用的总字节数。

    直接缓冲区释放内存的方法

    1. 手动释放空间
    package me.qianlv;
    
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.nio.ByteBuffer;
    import java.util.concurrent.TimeUnit;
    
    /**
     * @author xiaoshu
     * 直接缓冲区释放内存方法
     * 1. 手动释放
     * 2. 交给JVM处理
     * <p>
     * 此程序运行的效果就是1秒钟之后立即回收内存
     * 也就是回收"直接缓冲区"所占用的内存
     */
    public class Test9 {
        public static void main(String[] args) throws InterruptedException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
            System.out.println("A");
            ByteBuffer byteBuffer = ByteBuffer.allocateDirect(Integer.MAX_VALUE);
            System.out.println("B");
            byte[] byteArray = new byte[]{1};
            System.out.println(Integer.MAX_VALUE);
            for (int i = 0; i < Integer.MAX_VALUE; i++) {
                byteBuffer.put(byteArray);
            }
            System.out.println("put end.");
            TimeUnit.SECONDS.sleep(1);
            Method cleanerMethod = byteBuffer.getClass().getMethod("cleaner");
            cleanerMethod.setAccessible(true);
            Object returnValue = cleanerMethod.invoke(byteBuffer);
            Method cleanMethod = returnValue.getClass().getMethod("clean");
            cleanMethod.setAccessible(true);
            cleanMethod.invoke(returnValue);
        }
    }
    复制代码
    1. 交给JVM进行处理
    package me.qianlv;
    
    import java.nio.ByteBuffer;
    
    /**
     * @author xiaoshu
     * 直接缓冲区释放内存方法
     * 1. 手动释放
     * 2. 交给JVM处理
     * <p>
     * 此程序多次运行后,一直在耗费内存
     * 进程结束后,也不会马上回收内存
     * 而是会在某个时机触发GC垃圾回收器进行内存回收
     */
    public class Test10 {
        public static void main(String[] args) {
            System.out.println("A");
            ByteBuffer byteBuffer = ByteBuffer.allocateDirect(Integer.MAX_VALUE);
            System.out.println("B");
            byte[] byteArray = new byte[]{1};
            System.out.println(Integer.MAX_VALUE);
            for (int i = 0; i < Integer.MAX_VALUE; i++) {
                byteBuffer.put(byteArray);
            }
            System.out.println("put end.");
        }
    }
    复制代码

    此*.java类可以运行多次,产生多个进程,然后再查看内存使用情况会更加直观.

    参考:

    1. 《NIO与Socket编程技术指南》

    转载于:https://juejin.im/post/5d0638b4e51d45108223fc5c

    展开全文
  • nio创建缓冲区

    2009-07-29 11:17:56
    import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.IntBuffer; ...public class TestDirect { ... public static void main... //直接缓冲创建时间长,高效读写。 ByteBuffer bb = By...
    import java.nio.ByteBuffer;
    import java.nio.CharBuffer;
    import java.nio.IntBuffer;
    
    public class TestDirect {
    	public static void main(String[] args) {
    		//直接缓冲,创建时间长,高效读写。
    		ByteBuffer bb = ByteBuffer.allocateDirect(16);//先建byte的直接缓冲。
    		CharBuffer cb = bb.asCharBuffer();//其它类型的缓冲都是调用.as..Buffer()得到。
    		IntBuffer ib = bb.asIntBuffer();
    		System.out.println(bb.capacity());
    		System.out.println(cb.capacity());
    		System.out.println(ib.capacity());
    	}
    
    }
    
    
    
    
    
    

    展开全文
  • 直接缓冲区与非直接缓冲区 直接缓冲区与非直接缓冲区的理解 字节缓冲区要么是直接的,要么是非直接的。如果为直接字节缓冲区,则」ava虛拟机会尽最大努力直接在此缓冲区上执行本机/o操作。也就是说,在每次调用基础...
  • NIO缓冲区【复制缓冲区

    千次阅读 2019-04-10 22:21:54
      复制一个缓冲区创建一个新的 Buffer 对象,但并不复制数据。原始缓冲区和副本都会操作同样的数据元素。我们将以 CharBuffer 为例来演示,但同样的操作可被用于任何基本的缓冲区类型。 public abstract class ...
  • 一、NIO缓冲区 引言:Java NIO是jdk1.4引入的,官方给出的定义是NEW IO,是一种新的IO,也可以理解为no-block io(非阻塞io),NIO的出现和bio有相同的作用和目的,都是为了数据的输入和输出,但是方式有所不同,...
  • NIO缓冲区

    2020-05-21 15:39:53
    文章目录一 缓冲区1.1 什么是缓冲区1.2 直接缓冲区1.3 NIO缓冲区实现二 核心参数2.1 参数介绍2.2 参数限定条件2.3 参数终值2.4 参数操作API2.4.1 获取缓冲区尺寸2.4.2 获取缓冲区可读写尺寸限制2.4.3 设置缓冲区可...
  • nio-缓冲区

    2020-02-19 00:08:52
    NIO-缓冲区 nio是引入的新的io操作方式,支持面向缓冲区的、基于通道的IO操作,更高效的读取数据 与传统的IO的区别: IO NIO 面向流的 面向缓冲区的 阻塞 非阻塞 无 选择器 nio中的重要的两个概念:...
  • 直接缓冲区:通过allocate()方法分配缓冲区,将缓冲区建立在JVM的内存中。 直接缓冲区:通过allocateDirect()方法分配直接缓冲区,将缓冲区建立在物理内存中。可以提高效率。 字节缓冲区要么是直接的,要么...
  • /** 4,直接缓冲区与非直接缓冲区: * 非直接缓冲区 : 通过allocate()方法分配缓冲区,将缓冲区建立在JVM的内存中。 * 直接缓冲区 : 通过...//创建直接缓冲区 ByteBuffer buf = ByteBuffer.allocateDirect(1024...
  • Java NIO-缓冲区

    2017-04-09 22:38:10
    1.缓冲区操作,以从磁盘读取数据为例子:进程使用read请求系统填满缓冲区,内核随机向磁盘硬件发出指令,要求磁盘读取数据并放入内核缓冲区(通过DMA,直接内存读取,无需CPU协助)。然后内核把内存空间缓冲区数据...
  • nio缓冲区

    2018-08-27 22:12:52
    nio缓冲区     nio定义了7中缓冲区类型,就是八种java基本类型减去一个boolean型的。,包括父类Buffer,这些都是抽象类。缓冲区是包在对象内的基本数据元素数组,相对于一个简单的数组来说,Buffer将数组与对...
  • 直接缓冲区与非直接缓冲区别 分散读取与聚集写入 非直接缓冲区 通过 allocate() 方法分配缓冲区,将缓冲区建立在 JVM 的内存中! 案例展示 这里提供一个名为Python1,大小为397.1MB的zip文件; ...
  • 文章目录直接与非直接缓冲区直接缓冲区直接缓冲区demo 直接与非直接缓冲区 字节缓冲区要么是直接的,要么是非直接的。如果为直接字节缓冲区,则Java虚拟机会尽最大努力直接在此缓冲区上执行本机I/O操作。也就是说...
  • 直接缓冲区与非直接缓冲区:非直接缓冲区:通过 allocate() 方法分配缓冲区,将缓冲区建立在 JVM 的内存中直接缓冲区:通过 allocateDirect() 方法分配直接缓冲区,将缓冲区建立在物理内存中。可以提高效率 字节...
  • Java NIO Buffer 缓冲区

    2020-03-26 15:39:34
    本文介绍了 Java NIO 中 Buffer(缓冲区)的相关内容。。。
  • NIO缓冲区

    2020-02-08 05:54:00
    Java NIO简介Java NIO (New IO/Non Blocking IO),官方给的定义是New IO,但是我们也可以当作是Non Blocking IO,即...NIO与原来的IO有同样的作用和目的,但是使用的方式完全不同,NIO支 持面向缓冲区的、基于通道的...
  • package buffer; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.nio.ByteBuffer;...import java.nio.... * 测试直接缓冲区与堆内缓冲区的性能 * 因为Ni...
  • 直接缓冲区可以通过调用该缓冲区类的allocateDirect(int capacity) 方法创建,此方法返回的缓冲区进行分配和取消分配所需的成本要高于非直接缓冲区直接缓冲区的内容驻留在垃圾回收堆之外,因此他们对应用程序内存...
  • 概述 字节缓冲区要么是直接的,要么是非直接的。如果为直接字节缓冲区,则 Java 虚拟机会尽最大努力直接在机此缓冲区上执行本机 I/O ...直接字节缓冲区可以通过调用此类的 allocateDirect() 工厂方法 来创建。此方法
  • NIO缓冲区序言1.Java SE 的四大核心技术概述1.1 多线程1.1.1 进程与线程1.1.2 多任务1.2 并发技术1.3 Socket技术2.NIO概述2.1 什么是NIO2.2 NIO与普通IO相比的优点2.3 NIO高性能的核心原理3.Buffer类介绍3.1 缓冲...
  • 目录 Buffer介绍 ByteBuffer介绍 ByteBuffer案例 总结 Buffer介绍 ... 缓冲区(Buffer)是中NIO中基础的内容,...缓冲区工作与通道关联,我们不与通道直接进行交互,而是通过缓冲区将数据传送到通道里,或者从通道获...
  • NIO——缓冲区Buffer

    2019-10-13 22:47:07
    缓冲区(Buffer)是一个用于存取特定基本数据类型数据的容器,底层是这些基本数据类型的数组,由java.nio包定义,所有缓冲区都是Buffer抽象类的子类。主要用于与NIO通道进行交互,数据是从通道读入缓冲区,从缓冲区...
  • 字节缓冲区,顾名思义“缓冲”对象是字节,但是字节缓冲区又是一个...直接缓冲区: 在jvm中,字节数组可能不会在内存中连续存储,或者无用存储单元收集可能随时对其进行移动。在java中,数组是对象,而数据存储在对
  • java NIO 直接与非直接缓冲区

    千次阅读 2016-08-18 01:22:02
    ByteBuffer有两个创建缓冲区的方法: ... 这两个方法都是创建缓冲区的方法,使用直接缓冲区的时候,JVM虚拟机会直接在此缓冲区上执行 本机IO操作,也就是说,在每次调用基础操作系统的一个本
  • 一、nio 是什么? 1、Java NIO(New IO)是一个可以替代标准Java IO API的IO API(从Java 1.4开始) 2、Java NIO提供了与标准...2、NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中...
  • 缓冲区在java NIO中负责数据的存取。缓冲区就是数组,用于存储不同数据类型的数据

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 26,706
精华内容 10,682
关键字:

nio直接缓冲区创建