这几天使用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();
}
}
分享到:
相关推荐
之后,我们可以通过MappedByteBuffer的`get()`方法直接读取文件内容,无需逐字节地读取。 总结起来,MappedByteBuffer利用了操作系统级别的内存映射功能,实现了Java程序对大文件的高效访问,减少了系统开销,提升...
"读取文件数据并解析成bean实体类"这一主题涉及到的核心知识点主要包括文件操作、数据解析以及对象映射。下面将详细阐述这些概念及其应用。 1. **文件操作**:文件是数据存储的基本单位,通常以二进制或文本格式...
对于需要随机访问或文件特别大的情况,推荐使用`RandomAccessFile`和`FileChannel`的组合,特别是利用`MappedByteBuffer`进行内存映射文件读取。这种方式能够显著提高文件的读取速度,因为数据直接从磁盘映射到内存...
- `MappedByteBuffer inputBuffer = channel.map(FileChannel.MapMode.READ_ONLY, f.length()*begin_fz/begin_fm, f.length()*end_fz/end_fm);`将文件的一部分映射到内存中。 3. **数据读取** - 创建一个固定大小...
Java 读取文件的方法在Java编程中至关重要,无论是处理文本文件、二进制文件还是其他类型的数据,都需要灵活运用各种读取方式。以下是对Java读取文件的五种方法的详细说明,每种方法都有相应的代码示例: 1. **按...
通过映射文件到内存,`MappedByteBuffer`可以避免频繁的磁盘I/O操作,从而提高读取速度。 5. **局限性与注意事项**: - 自定义的按行读取方法可能不如标准的IO库(如BufferedReader的`readLine()`方法)那么健壮,...
Java语言在处理文件I/O操作时提供了多种方法,这些方法可以按照不同的策略读取文件,例如按字节或字符进行。下面将详细讲解Java中读取文件的主要方法,并结合给出的代码片段进行分析。 首先,Java中最基础的文件...
- 使用完毕后记得释放映射区域,否则可能导致内存泄漏。 2. **分块读取**: - 缓存大小的选择很重要,过大会占用过多内存,过小则可能导致频繁读取。 - 需要确保正确关闭文件通道,避免资源泄露。 #### 五、...
为了有效地读取大文件,可以使用缓冲区(Buffer)和内存映射文件(MappedByteBuffer)技术。下面将详细解释如何使用这些技术以及代码中的关键部分。 1. **缓冲区(Buffer)**: Java中的缓冲区是用于提高数据读写...
在处理大数据时,高效地读取大文件是至关重要的,特别是当文件的尺寸达到或超过2GB这样的大容量。在本篇文章中,我们将探讨几种针对大文件读取的有效策略,以确保程序性能不受影响,同时兼顾内存管理和资源优化。...
如果文件较大或操作频繁,可以考虑使用内存映射文件(MappedByteBuffer)提高读写效率,或者使用流式处理(BufferedReader/BufferedWriter)以减少内存占用。 总结来说,通过Java的Apache POI库,我们可以方便地...
- Java的`MappedByteBuffer`类允许将文件映射到内存,使得文件操作如同访问内存一样快速,适合处理大型文件。 9. **大数据量文件读取策略** - **分块读取**:对于大文件,不一次性加载到内存,而是按需分块读取。...
完成文件操作后,记得关闭打开的流,以释放资源。Java 7引入的try-with-resources语句可以简化这个过程: ```java try (BufferedReader br = new BufferedReader(new FileReader("example.txt"))) { // 读取操作...
在Java Web开发中,有时我们需要从应用程序的`classes`目录或者对应的`WEB-INF/classes`目录中读取资源文件,例如配置文件、静态内容或者数据库连接字符串等。这通常发生在我们想要在运行时加载非代码的资源,而这些...
Bug ID 4724038 (fs) Add unmap method to MappedByteBuffer
同时,完成文件读取后,必须关闭打开的文件通道和释放内存映射资源,以防止资源泄漏。 ### 六、代码实践 在具体的代码实现中,可以创建一个`ThreadPoolExecutor`实例来管理线程,每个线程使用`MappedByteBuffer`...
在读取和排序过程中,只将当前处理的小文件部分加载到内存,处理完后立即释放。 5. **并发控制**: - 使用多线程处理文件块,但注意IO操作本身不支持并发,所以线程应避免同时写入同一文件。可以使用`...
例如,我们可以使用Java的FileChannel类,通过MappedByteBuffer进行内存映射文件的读取,每次只处理一小部分数据。 接下来,排序算法的选择也很关键。对于小数据块,快速排序、归并排序或者插入排序可能是理想选择...
在Java编程中,有时我们需要将文件内容读取到内存中,以便进行进一步处理或传输。本文将介绍三种读取Java文件到byte数组的方法,供开发者参考。 ### 方法一:传统IO方式 这种方法是最常见的读取文件的方式,使用`...