发布于2021-06-14 10:38 阅读(972) 评论(0) 点赞(24) 收藏(0)
目录
①、不是虚拟机运行时数据区的一部分,也不是《Java虚拟机规范》中定义的内存区域
②、直接内存是在Java堆外的,直接向系统申请的内存空间
③、来源于NIO,通过存在堆中的DirectByteBuffer操作Native内存
④、通常,访问直接内存的速度会优于Java堆。即读写性能高
- 因此处于性能考虑,读写频繁的场合可能会考虑使用直接内存
- Java的NIO库允许Java使用直接内存,用于数据缓冲区
⑤、也可能导致OOM异常
⑥、由于直接内存在Java堆外,因此它的大小不会直接受限于-Xmx指定的最大堆大小,但是系统内存时有限的,Java堆和直接内存的总和依然受限于操作系统能给的最大内存
⑦缺点
- 分配的回收成本较高
- 不受JVM内存回收管理
⑧、直接内存大小可以通过MaxDirectMemorySize设置
⑨、如果不指定,默认与堆的最大值-Xmx参数值一致
- package com.atguigu.java;
-
- import java.nio.ByteBuffer;
- import java.util.Scanner;
-
- /**
- * IO NIO (New IO / Non-Blocking IO)
- * byte[] / char[] Buffer
- * Stream Channel
- *
- * 查看直接内存的占用与释放
- * @author
- * @create
- */
- public class BufferTest {
- private static final int BUFFER = 1024 * 1024 * 1024;//1GB
-
- public static void main(String[] args){
- //直接分配本地内存空间
- ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BUFFER);
- System.out.println("直接内存分配完毕,请求指示!");
-
- Scanner scanner = new Scanner(System.in);
- scanner.next();
-
- System.out.println("直接内存开始释放!");
- byteBuffer = null;
- System.gc();
- scanner.next();
- }
- }
- package com.atguigu.java;
-
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.nio.ByteBuffer;
- import java.nio.channels.FileChannel;
-
- /**
- * @author
- * @create
- */
- public class BufferTest1 {
-
- private static final String TO = "F:\\test\\异界BD中字.mp4";
- private static final int _100Mb = 1024 * 1024 * 100;
-
- public static void main(String[] args) {
- long sum = 0;
- String src = "F:\\test\\异界BD中字.mp4";
- for (int i = 0; i < 3; i++) {
- String dest = "F:\\test\\异界BD中字_" + i + ".mp4";
- // sum += io(src,dest);//54606
- sum += directBuffer(src,dest);//50244
- }
-
- System.out.println("总花费的时间为:" + sum );
- }
-
- private static long directBuffer(String src,String dest) {
- long start = System.currentTimeMillis();
-
- FileChannel inChannel = null;
- FileChannel outChannel = null;
- try {
- inChannel = new FileInputStream(src).getChannel();
- outChannel = new FileOutputStream(dest).getChannel();
-
- ByteBuffer byteBuffer = ByteBuffer.allocateDirect(_100Mb);
- while (inChannel.read(byteBuffer) != -1) {
- byteBuffer.flip();//修改为读数据模式
- outChannel.write(byteBuffer);
- byteBuffer.clear();//清空
- }
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- if (inChannel != null) {
- try {
- inChannel.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- }
- if (outChannel != null) {
- try {
- outChannel.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- }
- }
-
- long end = System.currentTimeMillis();
- return end - start;
-
- }
-
- private static long io(String src,String dest) {
- long start = System.currentTimeMillis();
-
- FileInputStream fis = null;
- FileOutputStream fos = null;
- try {
- fis = new FileInputStream(src);
- fos = new FileOutputStream(dest);
- byte[] buffer = new byte[_100Mb];
- while (true) {
- int len = fis.read(buffer);
- if (len == -1) {
- break;
- }
- fos.write(buffer, 0, len);
- }
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- if (fis != null) {
- try {
- fis.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- }
- if (fos != null) {
- try {
- fos.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- }
- }
-
-
- long end = System.currentTimeMillis();
-
- return end - start;
- }
- }
本地内存的OOM
- package com.atguigu.java;
-
- import java.nio.ByteBuffer;
- import java.util.ArrayList;
-
- /**
- * 本地内存的OOM: OutOfMemoryError: Direct buffer memory
- *
- * @author
- * @create
- */
- public class BufferTest2 {
- private static final int BUFFER = 1024 * 1024 * 20;//20MB
-
- public static void main(String[] args) {
- ArrayList<ByteBuffer> list = new ArrayList<ByteBuffer>();
-
- int count = 0;
- try {
- while(true){
- ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BUFFER);
- list.add(byteBuffer);
- count++;
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- } finally {
- System.out.println(count);
- }
-
-
- }
- }
设置最大本地内存后的OOM
- package com.atguigu.java;
-
- import sun.misc.Unsafe;
-
- import java.lang.reflect.Field;
-
- /**
- * -Xmx20m -XX:MaxDirectMemorySize=10m
- * @author
- * @create
- */
- public class MaxDirectMemorySizeTest {
- private static final long _1MB = 1024 * 1024;
-
- public static void main(String[] args) throws IllegalAccessException {
- Field unsafeField = Unsafe.class.getDeclaredFields()[0];
- unsafeField.setAccessible(true);
- Unsafe unsafe = (Unsafe)unsafeField.get(null);
- while(true){
- unsafe.allocateMemory(_1MB);
- }
-
- }
- }
原文链接:https://blog.csdn.net/Choco1ove/article/details/117806236
作者:你不要惹我
链接:http://www.javaheidong.com/blog/article/222683/c81fdbf02f444e17f0c9/
来源:java黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 java黑洞网 All Rights Reserved 版权所有,并保留所有权利。京ICP备18063182号-2
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!