本文介绍了尝试释放内存时为EXCEPTION_ACCESS_VIOLATION(0xc0000005)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过LWJGL使用opencl时,出现以下错误消息:

When using opencl via LWJGL, I am getting the following error message:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000002201971, pid=8476, tid=8920
#
# JRE version: 7.0_03-b05
# Java VM: Java HotSpot(TM) 64-Bit Server VM (22.1-b02 mixed mode windows-amd64     compressed oops)
# Problematic frame:
# C  [OpenCL.dll+0x1971]
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of    Windows
#
# An error report file with more information is saved as:
# V:\Documents\NetBeansProjects\LWJGL\hs_err_pid8476.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.sun.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

我正在使用的源代码:

import java.awt.*;
import java.awt.image.*;
import java.io.*;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.*;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.vecmath.Point3f;
import org.lwjgl.*;
import static org.lwjgl.opencl.CL10.*;
import org.lwjgl.opencl.*;

public class RayTracer {
    public static void main(String[] args) throws Exception {
        LoadSource();
        RayTracer rayTracer = new RayTracer();
        rayTracer.CLRender();
    }
    JFrame frame;
    BufferedImage scene;
    Sphere sphere;
    static final float SAMPLES = 4f;
    Graphics graphics;
    BufferStrategy bufferSrategy;
    final AtomicBoolean redraw = new AtomicBoolean();
    IntBuffer temp;
    static String source = "";

RayTracer() throws LWJGLException {
    frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
    frame.setVisible(true);

    frame.createBufferStrategy(2);
    bufferSrategy = frame.getBufferStrategy();

    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice gd = ge.getDefaultScreenDevice();
    GraphicsConfiguration gc = gd.getDefaultConfiguration();

    scene = gc.createCompatibleImage((int) (frame.getWidth()), (int) (frame.getHeight()));
    sphere = new Sphere();
    sphere.location = new Point3f(0, 0, -5);
    startDrawThread();

}

void CLRender() throws LWJGLException {


        // initialization
        CL.create();
        CLPlatform platform = CLPlatform.getPlatforms().get(0);
        List<CLDevice> devices = platform.getDevices(CL_DEVICE_TYPE_GPU);
        CLContext context = CLContext.create(platform, devices, null, null, null);
        CLCommandQueue queue = clCreateCommandQueue(context, devices.get(0), CL_QUEUE_PROFILING_ENABLE, null);



        // program/kernel creation

        CLProgram program = clCreateProgramWithSource(context, source, null);
        try {
            Util.checkCLError(clBuildProgram(program, devices.get(0), "", null));
            //check for problem
        } catch (OpenCLException e) {
            ByteBuffer buffer = BufferUtils.createByteBuffer(1024 * 40);
            buffer.rewind();
            PointerBuffer pb = PointerBuffer.allocateDirect(1);
            Util.checkCLError(clGetProgramBuildInfo(program, devices.get(0), CL_PROGRAM_BUILD_STATUS, buffer, null));
            switch (buffer.get(0)) {
                case CL_BUILD_NONE:
                    System.out.println("build none");
                    break;
                case CL_BUILD_ERROR:
                    System.out.println("build error");
                    break;
                case CL_BUILD_IN_PROGRESS:
                    System.out.println("build in progress");
                    break;
                case CL_BUILD_SUCCESS:
                    System.out.println("build successful");
                    break;
            }
            buffer.rewind();
            Util.checkCLError(clGetProgramBuildInfo(program, devices.get(0), CL_PROGRAM_BUILD_LOG, buffer, pb));
            print(buffer, pb.get());
            System.exit(1);
        }
        // set kernel
        CLKernel kernel = clCreateKernel(program, "trace", null);
        final int width = scene.getWidth();
        final int height = scene.getHeight();
        FloatBuffer sphereRadius, sphereLocation, light, imageDim, samples;
        IntBuffer color;
        Light movingLight = new Light(new Point3f(), Color.ORANGE);
        movingLight.activate();
        try {
            for (float z = 0;; z += .01f) {
                //set Ligh Poition
                movingLight.position = new Point3f(-.5f, (float) (10 * Math.cos(z)), (float) (10 * Math.sin(z)));

                //Put data in Buffers
                float[] lights = Light.getLights();
                sphereRadius = toFloatBuffer(new float[]{sphere.radius.x, sphere.radius.y, sphere.radius.z});
                sphereLocation = toFloatBuffer(new float[]{sphere.location.x, sphere.location.y, sphere.location.z});
                light = toFloatBuffer(lights);
                imageDim = toFloatBuffer(new float[]{width, height, -1f});
                samples = toFloatBuffer(new float[]{SAMPLES});
                color = toIntBuffer(new int[width * height]);


                // send to open CL
                CLMem sphereRadiusMem = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sphereRadius, null);
                clEnqueueWriteBuffer(queue, sphereRadiusMem, 1, 0, sphereRadius, null, null);
                CLMem lightMem = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, light, null);
                clEnqueueWriteBuffer(queue, lightMem, 1, 0, light, null, null);
                CLMem imageDimMem = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, imageDim, null);
                clEnqueueWriteBuffer(queue, imageDimMem, 1, 0, imageDim, null, null);
                CLMem samplesMem = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, samples, null);
                clEnqueueWriteBuffer(queue, samplesMem, 1, 0, samples, null, null);
                CLMem sphereLocationMem = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sphereLocation, null);
                clEnqueueWriteBuffer(queue, sphereLocationMem, 1, 0, sphereLocation, null, null);
                CLMem colorMem = clCreateBuffer(context, CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, color, null);

                // execution
                PointerBuffer kernel1DGlobalWorkSize = BufferUtils.createPointerBuffer(2);
                kernel1DGlobalWorkSize.put(0, width);
                kernel1DGlobalWorkSize.put(1, height);
                kernel.setArg(0, sphereRadiusMem);
                kernel.setArg(1, sphereLocationMem);
                kernel.setArg(2, lightMem);
                kernel.setArg(3, imageDimMem);
                kernel.setArg(4, samplesMem);
                kernel.setArg(5, colorMem);
                clEnqueueNDRangeKernel(queue, kernel, 2, null, kernel1DGlobalWorkSize, null, null, null);

                // read the results back
                clEnqueueReadBuffer(queue, colorMem, 1, 0, color, null, null);

                //transfer to Image
                setScene(color);

                //clean up memory
                clReleaseMemObject(colorMem);
                clReleaseMemObject(imageDimMem);
                clReleaseMemObject(lightMem);
                clReleaseMemObject(samplesMem);
                //clReleaseMemObject(sphereLocationMem);    //uncomenting results in nasty error
                clReleaseMemObject(sphereLocationMem);
                clReleaseMemObject(sphereRadiusMem);

            }
        } finally {
            // teardown
            clFinish(queue);
            clReleaseKernel(kernel);
            clReleaseProgram(program);
            clReleaseCommandQueue(queue);
            CL.destroy();
        }
    }
}

在底部附近,您会看到一条注释clReleaseMemObject(sphereLocationMem);.如果我对此发表评论,它可以正常工作.其他所有对clReleaseMemory()的调用都可以正常工作,为什么这会引发错误?

Near the bottom you will see a commented clReleaseMemObject(sphereLocationMem); When ever this is uncommented, I get the error message. If I leave it commented, it works fine. All the other calls to clReleaseMemory() work fine, why does this one throw an error?

推荐答案

SphereLocationMem在指示的行未注释时被释放两次,位于:

SphereLocationMem is being released twice when the indicated line is uncommented, at:

//clReleaseMemObject(sphereLocationMem);    //uncomenting results in nasty error
clReleaseMemObject(sphereLocationMem);

领先于所示的访问冲突.对该行进行注释后,很可能可以正常工作.

Leading to the access violation indicated. Having that line commented, it's most likely working correctly.

这篇关于尝试释放内存时为EXCEPTION_ACCESS_VIOLATION(0xc0000005)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 00:01