[英]EXCEPTION_ACCESS_VIOLATION JVM crashes when using Window Builder
[英]EXCEPTION_ACCESS_VIOLATION Error when using stbi_load
我正在尝试使用stbi_load
将图像加载到 ByteBuffer 中。 但是,控制台中出现以下错误
Java运行时环境已经检测到了致命错误:exception_access_violation(0xc00005555555005)at pc = 0x0000007ffb5bbb63b63b63b63b8c,pid = 5424,tid = 0x0000000000000000000000001364 jre runjd runjd runjd run.jd run.jd run.jd run.jd run.jd run.jd run.jdk univers(8.01) OpenJDK 64 位服务器 VM(25.312-b07 混合模式 windows-amd64 压缩 oops) 有问题的框架:C [lwjgl_stb.dll+0x3b8c] 无法写入核心转储。 Windows 的客户端版本默认不启用 Minidumps 包含更多信息的错误报告文件保存为:C:\Users\nottn\eclipse-workspace\Bon Sea\hs_err_pid5424.log 如果您想提交错误报告,请访问: https://bugzilla.redhat.com/enter_bug.cgi崩溃发生在 Java 本机代码的虚拟机之外。 请参阅有问题的框架以了解在何处报告错误。
这是产生此错误的代码(请记住我正在使用 LWJGL 3)
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.stb.STBImage.*;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.awt.image.BufferedImage;
public class Texture {
private int id;
private IntBuffer width, height, n;
public Texture(String filename)
{
BufferedImage bi;
try
{
bi = ImageIO.read(new File("./sprites/" + filename));
width = IntBuffer.allocate(bi.getWidth());
width.put(bi.getWidth());
height = IntBuffer.allocate(bi.getHeight());
height.put(bi.getHeight());
n = IntBuffer.allocate(GL_RGBA);
n.put(GL_RGBA);
ByteBuffer data = stbi_load("/Users/nottn/eclipse-workspace/Bon Sea/sprites/test.png", width, height, n, STBI_rgb_alpha);
id = glGenTextures();
glBindTexture(GL_TEXTURE_2D, id);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width.array()[0], height.array()[0], 0, GL_RGBA, GL_BYTE, data);
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void Bind() {
glBindTexture(GL_TEXTURE_2D, id);
}
}
这是生成的日志文件Pastebin Log Here
非常感谢任何关于为什么会发生此错误的答案。
崩溃的原因是您使用的是由 Java arrays 支持的非直接NIO 缓冲区,即IntBuffer.allocate(...)
而不是由堆外(本机)虚拟支持的IntBuffer.allocateDirect(...)
memory。
LWJGL 基本上只是将stbi_load(...)
调用转发/定向到本机库。 And for the native library to be able to put the memory into a supplied memory region, that region must be an actual "off-heap" (off-heap as in: it is outside the Java garbage-collected heap) memory region of the进程的虚拟 memory。
当您调用任何 LWJGL 提供的采用 NIO 缓冲区(例如stbi_load(...)
)的方法时,LWJGL 将做的是读取(隐藏的) Buffer.address
字段的值,该字段仅在所述缓冲区是直接(或“堆外”)缓冲区。
对于由 Java 原语 arrays 支持的非直接或(堆上)缓冲区,该字段为0
,因此本机库将访问零地址,这最终导致崩溃。
为了解决这个问题,您应该只创建直接NIO 缓冲区。
有关非直接与直接 NIO 缓冲区的解释,请参阅ByteBuffer class 的 JavaDocs 。
我还强烈推荐阅读这篇 LWJGL 3 博客文章,它提供了关于 LWJGL 3 中本机内存管理的更多见解和更多策略。
不确定这是否是您问题的答案,但是当我不小心移动类似代码以在行“GL.createCapabilities();”之前执行时,我遇到了那个错误
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.