`
Jen
  • 浏览: 57428 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

MappedByteBuffer强制释放后读取引发jvm crash

    博客分类:
  • java
阅读更多

 

这几天使用MappedByteBuffer对系统进行了实现,在压测过程中发现启动多个group订阅时服务端会发生jvm crash ,排查后找到了原因,记录一下。

 

部分信息如下:

#

# A fatal error has been detected by the Java Runtime Environment:

#

#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x01b8d4d7, pid=10236, tid=8452

#

# JRE version: 6.0_18-b02

# Java VM: Java HotSpot(TM) Client VM (16.0-b09 mixed mode, sharing windows-x86 )

# Problematic frame:

# J  java.nio.DirectByteBuffer.get(I)B

#

# An error report file with more information is saved as:

# D:\workspace_new\metamorphosis\metamorphosis-server\hs_err_pid10236.log

#

# If you would like to submit a bug report, please visit:

#   http://java.sun.com/webapps/bugreport/crash.jsp

#

 

原因是在MappedByteBuffer释放后再对它进行读操作的话就会引发这个crash,在并发情况下很容易正在释放时另一个线程正开始读取,于是crash就发生了。下面这个测试代码可以重现:

 

@Test

public void unmapAndRead()throws Exception {

  File file =new File("unmapAndRead.txt");

  FileChannel fileChannel =new RandomAccessFile(file,"rw").getChannel();

  MappedByteBuffer buf = fileChannel.map(MapMode.READ_WRITE, 0, 4096);

  buf.putInt(5);

  buf.force();

  this.unmap(buf);

  buf.get(2);//Crash occur

}

 

void unmap(finalMappedByteBuffer mappedByteBuffer) {

  try {

    if (mappedByteBuffer ==null) {

    return;

  }

  mappedByteBuffer.force();

  AccessController.doPrivileged(new PrivilegedAction<Object>() {

  @Override

  public Object run() {

    try {

       Method getCleanerMethod =      mappedByteBuffer.getClass().getMethod("cleaner",new Class[0]);

       getCleanerMethod.setAccessible(true);

       sun.misc.Cleaner cleaner =

       (sun.misc.Cleaner)getCleanerMethod.invoke(mappedByteBuffer,new Object[0]);

       cleaner.clean();

    }

    catch (Exception e) {

       e.printStackTrace();

    }

    return null;

   }

  });

 

 }

catch (Exception e) {

   e.printStackTrace();

}

}

 

2
2
分享到:
评论
1 楼 Caelebs 2017-08-14  
  sun.misc.Cleaner 这个rt包里面的东西限制访问, 没找到咋整

相关推荐

    深入浅出MappedByteBuffer.pdf

    之后,我们可以通过MappedByteBuffer的`get()`方法直接读取文件内容,无需逐字节地读取。 总结起来,MappedByteBuffer利用了操作系统级别的内存映射功能,实现了Java程序对大文件的高效访问,减少了系统开销,提升...

    读取文件数据并解析成bean实体类

    "读取文件数据并解析成bean实体类"这一主题涉及到的核心知识点主要包括文件操作、数据解析以及对象映射。下面将详细阐述这些概念及其应用。 1. **文件操作**:文件是数据存储的基本单位,通常以二进制或文本格式...

    java读取超大文本文件

    对于需要随机访问或文件特别大的情况,推荐使用`RandomAccessFile`和`FileChannel`的组合,特别是利用`MappedByteBuffer`进行内存映射文件读取。这种方式能够显著提高文件的读取速度,因为数据直接从磁盘映射到内存...

    java nio 包读取超大数据文件

    - `MappedByteBuffer inputBuffer = channel.map(FileChannel.MapMode.READ_ONLY, f.length()*begin_fz/begin_fm, f.length()*end_fz/end_fm);`将文件的一部分映射到内存中。 3. **数据读取** - 创建一个固定大小...

    java 读取文件方法的总结

    Java 读取文件的方法在Java编程中至关重要,无论是处理文本文件、二进制文件还是其他类型的数据,都需要灵活运用各种读取方式。以下是对Java读取文件的五种方法的详细说明,每种方法都有相应的代码示例: 1. **按...

    NIO按行读取数据

    通过映射文件到内存,`MappedByteBuffer`可以避免频繁的磁盘I/O操作,从而提高读取速度。 5. **局限性与注意事项**: - 自定义的按行读取方法可能不如标准的IO库(如BufferedReader的`readLine()`方法)那么健壮,...

    Java读取文件方法大全

    Java语言在处理文件I/O操作时提供了多种方法,这些方法可以按照不同的策略读取文件,例如按字节或字符进行。下面将详细讲解Java中读取文件的主要方法,并结合给出的代码片段进行分析。 首先,Java中最基础的文件...

    java大文件读取-乔乐共享

    - 使用完毕后记得释放映射区域,否则可能导致内存泄漏。 2. **分块读取**: - 缓存大小的选择很重要,过大会占用过多内存,过小则可能导致频繁读取。 - 需要确保正确关闭文件通道,避免资源泄露。 #### 五、...

    java读取大文件

    为了有效地读取大文件,可以使用缓冲区(Buffer)和内存映射文件(MappedByteBuffer)技术。下面将详细解释如何使用这些技术以及代码中的关键部分。 1. **缓冲区(Buffer)**: Java中的缓冲区是用于提高数据读写...

    有效率的读取大文件(2G)

    在处理大数据时,高效地读取大文件是至关重要的,特别是当文件的尺寸达到或超过2GB这样的大容量。在本篇文章中,我们将探讨几种针对大文件读取的有效策略,以确保程序性能不受影响,同时兼顾内存管理和资源优化。...

    读取excel值替换文件内容

    如果文件较大或操作频繁,可以考虑使用内存映射文件(MappedByteBuffer)提高读写效率,或者使用流式处理(BufferedReader/BufferedWriter)以减少内存占用。 总结来说,通过Java的Apache POI库,我们可以方便地...

    java io读取文件

    - Java的`MappedByteBuffer`类允许将文件映射到内存,使得文件操作如同访问内存一样快速,适合处理大型文件。 9. **大数据量文件读取策略** - **分块读取**:对于大文件,不一次性加载到内存,而是按需分块读取。...

    IO文件读取

    完成文件操作后,记得关闭打开的流,以释放资源。Java 7引入的try-with-resources语句可以简化这个过程: ```java try (BufferedReader br = new BufferedReader(new FileReader("example.txt"))) { // 读取操作...

    javaweb 读取 classes 下的文件

    在Java Web开发中,有时我们需要从应用程序的`classes`目录或者对应的`WEB-INF/classes`目录中读取资源文件,例如配置文件、静态内容或者数据库连接字符串等。这通常发生在我们想要在运行时加载非代码的资源,而这些...

    Bug ID 4724038 (fs) Add unmap method to MappedByteBuffer

    Bug ID 4724038 (fs) Add unmap method to MappedByteBuffer

    Java多线程读取大文件

    同时,完成文件读取后,必须关闭打开的文件通道和释放内存映射资源,以防止资源泄漏。 ### 六、代码实践 在具体的代码实现中,可以创建一个`ThreadPoolExecutor`实例来管理线程,每个线程使用`MappedByteBuffer`...

    java对大数据量文件内容的多线程读取和排序.pdf

    在读取和排序过程中,只将当前处理的小文件部分加载到内存,处理完后立即释放。 5. **并发控制**: - 使用多线程处理文件块,但注意IO操作本身不支持并发,所以线程应避免同时写入同一文件。可以使用`...

    Java 大文件读取排序

    例如,我们可以使用Java的FileChannel类,通过MappedByteBuffer进行内存映射文件的读取,每次只处理一小部分数据。 接下来,排序算法的选择也很关键。对于小数据块,快速排序、归并排序或者插入排序可能是理想选择...

    读取Java文件到byte数组的三种方法(总结)

    在Java编程中,有时我们需要将文件内容读取到内存中,以便进行进一步处理或传输。本文将介绍三种读取Java文件到byte数组的方法,供开发者参考。 ### 方法一:传统IO方式 这种方法是最常见的读取文件的方式,使用`...

Global site tag (gtag.js) - Google Analytics