`

JVM直接内存

    博客分类:
  • jdk
 
阅读更多

概述

直接内存并不是虚拟机运行时数据区的一部分,也不是Java 虚拟机规范中农定义的内存区域。在JDK1.4 中新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区(Buffer)的I/O 方式,它可以使用native 函数库直接分配堆外内存,然后通脱一个存储在Java堆中的DirectByteBuffer 对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在Java堆和Native堆中来回复制数据。

  • 本机直接内存的分配不会受到Java 堆大小的限制,受到本机总内存大小限制

  • 配置虚拟机参数时,不要忽略直接内存 防止出现OutOfMemoryError异常

直接内存(堆外内存)与堆内存比较

  1. 直接内存申请空间耗费更高的性能,当频繁申请到一定量时尤为明显
  2. 直接内存IO读写的性能要优于普通的堆内存,在多次读写操作的情况下差异明显
package com.xnccs.cn.share;

import java.nio.ByteBuffer;


/**
 * 直接内存 与  堆内存的比较
 */
public class ByteBufferCompare {


    public static void main(String[] args) {
        allocateCompare();   //分配比较
        operateCompare();    //读写比较
    }

    /**
     * 直接内存 和 堆内存的 分配空间比较
     * 
     * 结论: 在数据量提升时,直接内存相比非直接内的申请,有很严重的性能问题
     * 
     */
    public static void allocateCompare(){
        int time = 10000000;    //操作次数                           


        long st = System.currentTimeMillis();
        for (int i = 0; i < time; i++) {

            //ByteBuffer.allocate(int capacity)   分配一个新的字节缓冲区。
            ByteBuffer buffer = ByteBuffer.allocate(2);      //非直接内存分配申请     
        }
        long et = System.currentTimeMillis();

        System.out.println("在进行"+time+"次分配操作时,堆内存 分配耗时:" + (et-st) +"ms" );

        long st_heap = System.currentTimeMillis();
        for (int i = 0; i < time; i++) {
            //ByteBuffer.allocateDirect(int capacity) 分配新的直接字节缓冲区。
            ByteBuffer buffer = ByteBuffer.allocateDirect(2); //直接内存分配申请
        }
        long et_direct = System.currentTimeMillis();

        System.out.println("在进行"+time+"次分配操作时,直接内存 分配耗时:" + (et_direct-st_heap) +"ms" );

    }

    /**
     * 直接内存 和 堆内存的 读写性能比较
     * 
     * 结论:直接内存在直接的IO 操作上,在频繁的读写时 会有显著的性能提升
     * 
     */
    public static void operateCompare(){
        int time = 1000000000;

        ByteBuffer buffer = ByteBuffer.allocate(2*time);  
        long st = System.currentTimeMillis();
        for (int i = 0; i < time; i++) {

            //  putChar(char value) 用来写入 char 值的相对 put 方法
            buffer.putChar('a');
        }
        buffer.flip();
        for (int i = 0; i < time; i++) {
            buffer.getChar();
        }
        long et = System.currentTimeMillis();

        System.out.println("在进行"+time+"次读写操作时,非直接内存读写耗时:" + (et-st) +"ms");

        ByteBuffer buffer_d = ByteBuffer.allocateDirect(2*time);
        long st_direct = System.currentTimeMillis();
        for (int i = 0; i < time; i++) {

            //  putChar(char value) 用来写入 char 值的相对 put 方法
            buffer_d.putChar('a');
        }
        buffer_d.flip();
        for (int i = 0; i < time; i++) {
            buffer_d.getChar();
        }
        long et_direct = System.currentTimeMillis();

        System.out.println("在进行"+time+"次读写操作时,直接内存读写耗时:" + (et_direct - st_direct) +"ms");
    }
}

 

 

输出: 

在进行10000000次分配操作时,堆内存 分配耗时:12ms 
在进行10000000次分配操作时,直接内存 分配耗时:8233ms 
在进行1000000000次读写操作时,非直接内存读写耗时:4055ms 
在进行1000000000次读写操作时,直接内存读写耗时:745ms

可以自己设置不同的time 值进行比较

 

分析

从数据流的角度,来看

非直接内存作用链: 
本地IO –>直接内存–>非直接内存–>直接内存–>本地IO 
直接内存作用链: 
本地IO–>直接内存–>本地IO

 

直接内存使用场景

  • 有很大的数据需要存储,它的生命周期很长
  • 适合频繁的IO操作,例如网络并发场景

  

java 直接内存回收

 是通过GC回收的,不过GC只会在老年区满了触发Full GC时,才会去顺便清理直接内存的废弃对象

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    java虚拟机jvm及Tomcat中的jvm有关内存的设置与调优

    ### Java虚拟机(JVM)内存设置与调优详解 #### 引言 在现代软件开发中,Java虚拟机(JVM)作为执行Java字节码的核心组件,其性能直接影响到Java应用的运行效率与稳定性。特别是在大数据处理场景下,合理设置JVM内存...

    JVM内存空间分配笔记

    - **优点**:解决了JVM无法直接操作底层代码的问题,提高了代码执行效率。 - **特点**:与Java虚拟机栈一样,每个线程拥有独立的本地方法栈。 #### 五、Java堆 Java堆是Java虚拟机所管理的内存中最大的一块,它是...

    idea插件JVM内存工具JProfiler11

    《深入理解IDEA插件JProfiler11:高效优化JVM内存》 在Java开发领域,高效运行和优化JVM内存是至关重要的。IntelliJ IDEA(简称Idea)作为广受欢迎的Java集成开发环境,提供了一系列强大的工具来帮助开发者进行性能...

    jvm内存监控工具使用

    Java Virtual Machine (JVM) 是运行 Java 应用程序的核心组件,其性能直接影响应用的响应速度和稳定性。JVM 的内存管理是性能优化的关键,尤其是在高并发环境下,合理的内存配置和监控显得尤为重要。本文将深入探讨 ...

    jvm的内存结构图的ppt模型分析.zip

    5. **直接内存**:不在JVM规范的内存结构中,但对性能有显著影响。它指的是通过NIO(New Input/Output)类直接分配的堆外内存,可以避免堆内存的分配和垃圾回收开销,但可能引发内存溢出问题。 理解JVM内存结构对于...

    JVM内存模型深度剖析与优化.pdf

    JVM内存模型是Java虚拟机的核心组件之一,它直接影响着Java应用程序的性能和可靠性。本文将深入剖析JVM内存模型的结构和工作机理,并讨论如何优化JVM参数以提高Java应用程序的性能。 一、JVM内存模型结构 JVM内存...

    JVM内存参数详解以及配置调优

    JVM 内存参数是 Java 虚拟机中最重要的参数之一,它直接影响着 Java 应用程序的性能和稳定性。在这个资源中,我们将详细讨论 JVM 内存参数的配置和调优,包括 JVM 的结构、内存管理、垃圾回收、堆和非堆内存、内存...

    Sun JVM原理与内存管理

    - `Unsafe.allocateMemory` 提供了一种不推荐的直接内存分配方式。 #### 五、内存回收 - **Hotspot 认为没有引用的对象是 dead 的**: - 通过可达性分析确定哪些对象仍然被引用,未被引用的对象被认为是 dead 的...

    初探JVM内存区域

    不属于JVM规范定义的内存区域,但在高性能应用中常见,如NIO(New Input/Output)库,通过直接内存可以绕过Java堆,提高性能。 了解这些内存区域的工作原理和交互方式,可以帮助我们诊断和解决Java应用的内存泄漏...

    解析JVM内存结构和6大区域

    JVM 的内存结构可以分为 6 个区域:PC 寄存器、JVM 栈、堆(Heap)、方法区、运行时常量池和直接内存。每个区域都有其特定的功能和作用,以下是对每个区域的详细介绍: PC 寄存器(PC Register) PC 寄存器是一块...

    java虚拟机内存(jdk1.7为例)-初版理解图.zip_java_jvm

    这个模型主要分为堆内存、栈内存、方法区、程序计数器、本地方法栈以及JVM直接内存等几个部分。 1. 堆内存(Heap Memory):这是Java对象的主要存储区域,所有的类实例和数组都在堆中分配内存。堆内存是JVM中最大的...

    JVM 深入学习教程深入分析JVM教程!jvm 内存原型,优化等等

    本教程将涵盖JVM内存模型、内存分配以及优化策略。 一、JVM内存模型 1. 堆内存:堆是所有线程共享的一块内存区域,主要用于存储对象实例。Java中的动态内存分配主要在堆上进行,垃圾收集器也会对堆进行管理,进行...

    推荐一些JVM原理,JVM调优,JVM内存模型,JAVA并发 电子书1

    总的来说,JVM原理、JVM调优、JVM内存模型和JAVA并发是Java程序员和系统管理员需要深入了解的知识点,因为它们直接影响到Java程序的性能和稳定性。了解这些知识点有助于开发者编写性能更优的代码,并在生产环境中对...

    如何配置Tomcat的JVM虚拟机内存大小

    ### 如何配置Tomcat的JVM虚拟机内存大小:深入解析与最佳实践 #### 引言 在IT领域,特别是Web应用服务器管理中,正确配置Java虚拟机(JVM)的内存大小对于确保应用程序的稳定性和性能至关重要。本文将详细探讨如何...

    Jvm对象内存分配理解

    Jvm 对象内存分配理解 Jvm 对象内存分配是 Java 虚拟机(Jvm)中的一种机制,用于在堆中分配对象的内存空间。该机制涉及到类加载检查、内存分配、对象初始化等多个步骤。 类加载检查 在 Jvm 对象内存分配中,首先...

    MyEclipse修改jvm内存.docx

    在开发过程中,jvm虚拟机的内存配置直接影响着开发的效率和稳定性。如果jvm虚拟机的内存配置不当,可能会导致内存溢出、应用程序崩溃等问题。因此,合理配置jvm虚拟机的内存是非常重要的。 配置jvm虚拟机的内存可以...

    JVM中[直接内存]的所有内容-pdf

    在JVM的内存模型中,直接内存(Direct Memory)是一个特殊的区域,虽然它并不属于标准的JVM运行时数据区,但对高性能的应用程序设计有着重要的影响。本文将深入探讨直接内存的概念、用途、优缺点以及如何进行配置。 ...

Global site tag (gtag.js) - Google Analytics