文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

详细总结Java堆栈内存、堆外内存、零拷贝浅析与代码实现

2024-04-02 19:55

关注

一、堆栈内存

堆栈内存,顾名思义,指的是堆内存以及栈内存,其中,堆内存是由Java GC进行管理的内存区域,而栈内存则是线程内存。关于栈内存,这里不去细说。以Hotspot为例,堆内存的简要结构如下图所示:

在这里插入图片描述

而堆栈的关系,我们可以通过一行简单的代码来理解:


public static void main(String[] args) {
    Object o = new Object();
}

上述代码主要完成了两件事,new Object( ) 在堆上开辟了一块内存,也就是说,new Object( )是分配在堆上的;而变量o,则是在线程main的栈上面的,它指向了new Object( ) 开辟的堆内存地址。简单来说,程序中创建的对象,都存储在堆内存中,栈内存包含对它的引用。

二、堆外内存

简单来说,除了堆栈内存,剩下的就都是堆外内存了(当然,这是从Java运行时内存的角度来看),堆外内存直接受操作系统管理,而不是虚拟机。而使用堆外内存的原因,主要有几点:

在这里插入图片描述

三、零拷贝

总结上述内容中对堆栈内存与堆外内存的说明,主要解决了两个疑问:“零拷贝”是从哪拷贝到哪?“零拷贝”是怎么优化掉这一拷贝操作的?

在Java中,提供了一些使用堆外内存以及DMA的方法,能够在很大程度上优化用户进程的IO效率。这里,给出一份拷贝文件的代码,分别使用BIO、NIO和使用堆外内存的NIO进行文件复制,简单对比其耗时。

这里我使用一个200MB左右的pdf文件进行拷贝操作,你可以另外指定更大的文件,文件越大对比越明显。这里我运行出来的延时,BIO的平均耗时1500ms上下,NIO耗时120ms左右, 使用堆外内存的NIO耗时100ms上下。


package top.jiangnanmax.nio;

import java.io.*;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;



public class CopyCompare {

    public static void main(String[] args) throws Exception {
        String inputFile = "/tmp/nio/input/HyperLedger.pdf";
        String outputFile = "/tmp/nio/output/HyperLedger.pdf";

        long start = System.currentTimeMillis();

        nioCopyByDirectMem(inputFile, outputFile);

        long end = System.currentTimeMillis();

        System.out.println("cost time: " + (end - start) + " ms");

        deleteFile(outputFile);
    }

    
    private static void bioCopy(String sourcePath, String destPath) throws Exception {
        File sourceFile = new File(sourcePath);
        File destFile = new File(destPath);
        if (!destFile.exists()) {
            destFile.createNewFile();
        }

        FileInputStream inputStream = new FileInputStream(sourceFile);
        FileOutputStream outputStream = new FileOutputStream(destFile);

        byte[] buffer = new byte[512];
        int lenRead;

        while ((lenRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, lenRead);
        }

        inputStream.close();
        outputStream.close();
    }

    
    private static void nioCopy(String sourcePath, String destPath) throws Exception {
        File sourceFile = new File(sourcePath);
        File destFile = new File(destPath);
        if (!destFile.exists()) {
            destFile.createNewFile();
        }

        FileInputStream inputStream = new FileInputStream(sourceFile);
        FileOutputStream outputStream = new FileOutputStream(destFile);

        FileChannel inputChannel = inputStream.getChannel();
        FileChannel outputChannel = outputStream.getChannel();

        // transferFrom底层调用的应该是sendfile
        // 直接在两个文件描述符之间进行了数据传输
        // DMA

        outputChannel.transferFrom(inputChannel, 0, inputChannel.size());

        inputChannel.close();
        outputChannel.close();
        inputStream.close();
        outputStream.close();

    }

    
    private static void nioCopyByDirectMem(String sourcePath, String destPath) throws Exception {
        File sourceFile = new File(sourcePath);
        File destFile = new File(destPath);
        if (!destFile.exists()) {
            destFile.createNewFile();
        }

        FileInputStream inputStream = new FileInputStream(sourceFile);
        FileOutputStream outputStream = new FileOutputStream(destFile);

        FileChannel inputChannel = inputStream.getChannel();
        FileChannel outputChannel = outputStream.getChannel();

        MappedByteBuffer buffer = inputChannel.map(FileChannel.MapMode.READ_ONLY, 0, inputChannel.size());

        outputChannel.write(buffer);

        inputChannel.close();
        outputChannel.close();
        inputStream.close();
        outputStream.close();

    }

    
    private static void deleteFile(String target) {
        File file = new File(target);
        file.delete();
    }

}

到此这篇关于详细总结Java堆栈内存、堆外内存、零拷贝浅析与代码实现的文章就介绍到这了,更多相关Java堆栈内存 堆外内存 零拷贝浅析内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯