Java直接内存与堆内存

NIO的Buffer提供了一个可以不经过JVM内存直接访问系统物理内存的类——DirectBuffer。 DirectBuffer类继承自ByteBuffer,但和普通的ByteBuffer不同,普通的ByteBuffer仍在JVM堆上分配内存,其最大内存受到最大堆内存的限制;而DirectBuffer直接分配在物理内存中,并不占用堆空间,其可申请的最大内存受操作系统限制。

直接内存的读写操作比普通Buffer快,但它的创建、销毁比普通Buffer慢。

因此直接内存使用于需要大内存空间且频繁访问的场合,不适用于频繁申请释放内存的场合。

以下是一些测试:

代码:

 1 public class DirectMemory {
 2     // 直接分配内存
 3     public static void directAccess() {
 4         long startTime = System.currentTimeMillis();
 5         ByteBuffer b = ByteBuffer.allocateDirect(500);
 6         for (int i = 0; i < 1000000; i++) {
 7             for (int j = 0; j < 99; j++)
 8                 b.putInt(j);
 9             b.flip();
10             for (int j = 0; j < 99; j++)
11                 b.getInt();
12             b.clear();
13         }
14         long endTime = System.currentTimeMillis();
15         System.out.println("directAccess:" + (endTime - startTime));
16     }
17
18     // 分配堆内存
19     public static void bufferAccess() {
20         long startTime = System.currentTimeMillis();
21         ByteBuffer b = ByteBuffer.allocate(500);
22         for (int i = 0; i < 1000000; i++) {
23             for (int j = 0; j < 99; j++)
24                 b.putInt(j);
25             b.flip();
26             for (int j = 0; j < 99; j++)
27                 b.getInt();
28             b.clear();
29         }
30         long endTime = System.currentTimeMillis();
31         System.out.println("bufferAccess" + (endTime - startTime));
32     }
33
34     public static void directAllocate() {
35         long startTime = System.currentTimeMillis();
36         for (int i = 0; i < 1000000; i++) {
37             ByteBuffer.allocateDirect(1000);
38         }
39         long endTime = System.currentTimeMillis();
40         System.out.println("directAllocate:" + (endTime - startTime));
41     }
42
43     public static void bufferAllocate() {
44         long startTime = System.currentTimeMillis();
45         for (int i = 0; i < 1000000; i++) {
46             ByteBuffer.allocate(1000);
47         }
48         long endTime = System.currentTimeMillis();
49         System.out.println("bufferAllocate:" + (endTime - startTime));
50     }
51
52     public static void main(String args[]) {
53
54         bufferAccess();
55         directAccess();
56
57         System.out.println();
58
59         bufferAllocate();
60         directAllocate();
61     }

结果:

bufferAccess175
directAccess:134

bufferAllocate:233
directAllocate:634
时间: 2024-12-28 08:15:49

Java直接内存与堆内存的相关文章

Java内存分配(直接内存、堆内存、Unsafel类、内存映射文件)

1.Java直接内存与堆内存-MarchOn 2.Java内存映射文件-MarchOn 3.Java Unsafe的使用-MarchOn 简单总结: 1.内存映射文件 读文件时候一般要两次复制:从磁盘复制到内核空间再复制到用户空间,内存映射文件避免了第二次复制,且内存分配在内核空间,应用程序访问的就是操作系统的内核内存空间,因此极大提高了读取效率.写文件同理. 2.堆内存分配与直接内存分配: Java申请空间时通常是从JVM堆内存分配的,即 ByteBuffer.allocate(int cap

Java中的栈内存和堆内存

为什么我们常说基本类型传递的是具体的值,而对象传递的是对象的内存地址呢.要搞清楚这个问题就要搞清楚栈内存与堆内存. java的内存分为栈内存和堆内存,两者的作用是不同的,我们可以简单的理解如下: 当我们创建一个java基本类型的变量时,只会用到栈内存而不会用到堆内存,栈内存中所存储的内容就是基本类型的值. int a = 3;  int b = 3; 执行第一行 int a = 3;时,JVM先会创建一个变量为a的引用,然后在栈内存中查找是否已经存在3这个值,没有找到,就会在栈内存中开辟一片区域

JVM存储位置分配——java中局部变量、实例变量和静态变量在方法区、栈内存、堆内存中的分配

Java中的变量根据不同的标准可以分为两类,以其引用的数据类型的不同来划分可分为“原始数据类型变量和引用数据类型变量”,以其作用范围的不同来区分可分为“局部变量,实例变量和静态变量”. 根据“Java中的变量与数据类型”中的介绍,“变量是在内存中分配的保留区域的名称.换句话说,它是一个内存位置的名称”,也就是说我们通过这个变量名字就可以找到一个指向这个变量所引用的数据的内存指针,根据变量的类型我们可以知道这个指针之后的几个字节里存储了这个变量所引用的数据. 所以,了解变量在方法区.栈内存.堆内存

栈内存和堆内存的区别

总结: 1 栈:为编译器自动分配和释放,如函数参数.局部变量.临时变量等等 2 堆:为成员分配和释放,由程序员自己申请.自己释放.否则发生内存泄露.典型为使用new申请的堆内容. 除了这两部分,还有一部分是: 3 静态存储区:内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.它主要存放静态数据.全局数据和常量. 转自: 栈内存和堆内存的区别(一个笔试题的一部分)http://blog.csdn.net/richerg85/article/details/19175133 笔试

(转)JVM内存管理-----堆内存

来源:http://blog.csdn.net/yu422560654/article/details/7952613 Heap堆内存理解 一个JVM实例只有一个堆内存,堆内存的大小是可以调节的.类加载器读取类文件后,需要把类文件.方法.常量放入到堆内存中,以便执行器执行,堆内存分为三部分: 1. Permanent Space 永久存储区 永久存储区是一个常驻内存区域,用于存放JDK自身所携带的Class,Interface的元数据,也就是说它存储的是运行环境必须的类信息,被装载进此区域的数据

JavaScript变量——栈内存or堆内存

原文  http://blog.csdn.net/xdd19910505/article/details/41900693 堆和栈这两个字我们已经接触多很多次,那么具体是什么存在栈中什么存在堆中呢?就拿 JavaScript 中的变量来说: 首先 JavaScript 中的变量分为基本类型和引用类型. 基本类型就是保存在栈内存中的简单数据段,而引用类型指的是那些保存在堆内存中的对象. 1 .基本类型 基本类型有 Undefined.Null.Boolean.Number 和String.这些类型

【内存】堆内存和栈内存

栈内存 编译器自己自动创建和释放 (私有的,如函数参数,局部变量,临时变量) 堆内存 程序员自己创建和释放的 (公有的) 栈内存比堆内存访问速度快 栈内存比堆内存容量小 栈内存的生命周期短而堆内存在整个程序运行中都存在(非手动清除) ? 原文地址:https://www.cnblogs.com/china-flint/p/9909362.html

JavaScript 数据结构与算法之美 - 栈内存与堆内存 、浅拷贝与深拷贝

前言 想写好前端,先练好内功. 栈内存与堆内存 .浅拷贝与深拷贝,可以说是前端程序员的内功,要知其然,知其所以然. 笔者写的 JavaScript 数据结构与算法之美 系列用的语言是 JavaScript ,旨在入门数据结构与算法和方便以后复习. 栈 定义 后进者先出,先进者后出,简称 后进先出(LIFO),这就是典型的栈结构. 新添加的或待删除的元素都保存在栈的末尾,称作栈顶,另一端就叫栈底. 在栈里,新元素都靠近栈顶,旧元素都接近栈底. 从栈的操作特性来看,是一种 操作受限的线性表,只允许在

js的栈内存和堆内存

栈内存和堆内存在了解一门语言底层数据结构上,挺重要的,做了个总结 JS中的栈内存堆内存 JS的内存空间分为栈(stack).堆(heap).池(一般也会归类为栈中). 其中栈存放变量,堆存放复杂对象,池存放常量,所以也叫常量池. 栈数据结构 栈是一种特殊的列表,栈内的元素只能通过列表的一端访问,这一端称为栈顶.栈被称为是一种后入先出(LIFO,last-in-first-out)的数据结构.由于栈具有后入先出的特点,所以任何不在栈顶的元素都无法访问.为了得到栈底的元素,必须先拿掉上面的元素. 堆

java基础:栈内存和堆内存

一:概念 Java编程语言把内存分成两种,一种叫做栈内存,一种叫做堆内存. Java的堆是一个运行时数据区,类的对象从中分配空间.这些对象通过new指令建立,它们不需要程序代码来显式的释放.堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据.但缺点是,由于要在运行时动态分配内存,存取速度较慢. 栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享.但缺点是,存在栈中的数据大小