概述
直接内存并不是虚拟机运行时数据区的一部分,也不是Java 虚拟机规范中农定义的内存区域。在JDK1.4 中新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区(Buffer)的I/O 方式,它可以使用native 函数库直接分配堆外内存,然后通脱一个存储在Java堆中的DirectByteBuffer 对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在Java堆和Native堆中来回复制数据。
-
本机直接内存的分配不会受到Java 堆大小的限制,受到本机总内存大小限制
-
配置虚拟机参数时,不要忽略直接内存 防止出现OutOfMemoryError异常
直接内存(堆外内存)与堆内存比较
- 直接内存申请空间耗费更高的性能,当频繁申请到一定量时尤为明显
- 直接内存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)内存设置与调优详解 #### 引言 在现代软件开发中,Java虚拟机(JVM)作为执行Java字节码的核心组件,其性能直接影响到Java应用的运行效率与稳定性。特别是在大数据处理场景下,合理设置JVM内存...
- **优点**:解决了JVM无法直接操作底层代码的问题,提高了代码执行效率。 - **特点**:与Java虚拟机栈一样,每个线程拥有独立的本地方法栈。 #### 五、Java堆 Java堆是Java虚拟机所管理的内存中最大的一块,它是...
《深入理解IDEA插件JProfiler11:高效优化JVM内存》 在Java开发领域,高效运行和优化JVM内存是至关重要的。IntelliJ IDEA(简称Idea)作为广受欢迎的Java集成开发环境,提供了一系列强大的工具来帮助开发者进行性能...
Java Virtual Machine (JVM) 是运行 Java 应用程序的核心组件,其性能直接影响应用的响应速度和稳定性。JVM 的内存管理是性能优化的关键,尤其是在高并发环境下,合理的内存配置和监控显得尤为重要。本文将深入探讨 ...
5. **直接内存**:不在JVM规范的内存结构中,但对性能有显著影响。它指的是通过NIO(New Input/Output)类直接分配的堆外内存,可以避免堆内存的分配和垃圾回收开销,但可能引发内存溢出问题。 理解JVM内存结构对于...
JVM内存模型是Java虚拟机的核心组件之一,它直接影响着Java应用程序的性能和可靠性。本文将深入剖析JVM内存模型的结构和工作机理,并讨论如何优化JVM参数以提高Java应用程序的性能。 一、JVM内存模型结构 JVM内存...
JVM 内存参数是 Java 虚拟机中最重要的参数之一,它直接影响着 Java 应用程序的性能和稳定性。在这个资源中,我们将详细讨论 JVM 内存参数的配置和调优,包括 JVM 的结构、内存管理、垃圾回收、堆和非堆内存、内存...
- `Unsafe.allocateMemory` 提供了一种不推荐的直接内存分配方式。 #### 五、内存回收 - **Hotspot 认为没有引用的对象是 dead 的**: - 通过可达性分析确定哪些对象仍然被引用,未被引用的对象被认为是 dead 的...
不属于JVM规范定义的内存区域,但在高性能应用中常见,如NIO(New Input/Output)库,通过直接内存可以绕过Java堆,提高性能。 了解这些内存区域的工作原理和交互方式,可以帮助我们诊断和解决Java应用的内存泄漏...
JVM 的内存结构可以分为 6 个区域:PC 寄存器、JVM 栈、堆(Heap)、方法区、运行时常量池和直接内存。每个区域都有其特定的功能和作用,以下是对每个区域的详细介绍: PC 寄存器(PC Register) PC 寄存器是一块...
这个模型主要分为堆内存、栈内存、方法区、程序计数器、本地方法栈以及JVM直接内存等几个部分。 1. 堆内存(Heap Memory):这是Java对象的主要存储区域,所有的类实例和数组都在堆中分配内存。堆内存是JVM中最大的...
本教程将涵盖JVM内存模型、内存分配以及优化策略。 一、JVM内存模型 1. 堆内存:堆是所有线程共享的一块内存区域,主要用于存储对象实例。Java中的动态内存分配主要在堆上进行,垃圾收集器也会对堆进行管理,进行...
总的来说,JVM原理、JVM调优、JVM内存模型和JAVA并发是Java程序员和系统管理员需要深入了解的知识点,因为它们直接影响到Java程序的性能和稳定性。了解这些知识点有助于开发者编写性能更优的代码,并在生产环境中对...
### 如何配置Tomcat的JVM虚拟机内存大小:深入解析与最佳实践 #### 引言 在IT领域,特别是Web应用服务器管理中,正确配置Java虚拟机(JVM)的内存大小对于确保应用程序的稳定性和性能至关重要。本文将详细探讨如何...
Jvm 对象内存分配理解 Jvm 对象内存分配是 Java 虚拟机(Jvm)中的一种机制,用于在堆中分配对象的内存空间。该机制涉及到类加载检查、内存分配、对象初始化等多个步骤。 类加载检查 在 Jvm 对象内存分配中,首先...
在开发过程中,jvm虚拟机的内存配置直接影响着开发的效率和稳定性。如果jvm虚拟机的内存配置不当,可能会导致内存溢出、应用程序崩溃等问题。因此,合理配置jvm虚拟机的内存是非常重要的。 配置jvm虚拟机的内存可以...
在JVM的内存模型中,直接内存(Direct Memory)是一个特殊的区域,虽然它并不属于标准的JVM运行时数据区,但对高性能的应用程序设计有着重要的影响。本文将深入探讨直接内存的概念、用途、优缺点以及如何进行配置。 ...