bytedeco / javacv

Java interface to OpenCV, FFmpeg, and more
Other
7.41k stars 1.57k forks source link

ContourArea causes program to crash #2117

Open iversionpeng opened 8 months ago

iversionpeng commented 8 months ago

question

log

  1. securityCheck 256 contours this=org.bytedeco.opencv.opencv_core.Mat[width=1,height=209,depth=-2147483616,channels=2]],address= 0x600002457dc0,reference={}
  2. checkLightNum 02 myMat=org.bytedeco.opencv.opencv_core.Mat[width=1,height=209,depth=-2147483616,channels=2],address=140261930922848,myMatreference=-1,contoursHash={}
  3. [GC (Allocation Failure) 267734K->14246K(595968K), 0.0013573 secs]
  4. Debug: Collecting org.bytedeco.javacpp.Pointer$NativeDeallocator[ownerAddress=0x600002457dc0,deallocatorAddress=0x12647c310]
  5. checkLightNum end myMat=org.bytedeco.opencv.opencv_core.Mat[width=10,height=19576,depth=-2147483640,channels=17],address=140261930922848,myMatreference=-1,contoursHash={}
  6. securityCheck 256 checkLightNum count=1,myMat=org.bytedeco.opencv.opencv_core.Mat[width=10,height=19576,depth=-2147483640,channels=17],address=140261930922848,reference=-1,contoursHash={}

Log conclusion: MatVector(address = 0x600002457dc0), Mat(address=140261930922848). From the above log, it can be seen that before MatVector is deallocated, Mat[width=1,height=209,depth=-2147483616,channels=2], After MatVector deallocate Mat[width=10,height=19576,depth=-2147483640,channels=17]

I am using a Mat object, but changes have occurred inside it, causing my program to crash? Why is it designed like this? How can I avoid this problem?

hs_error_pid.log

`SIGSEGV (0xb) at pc=0x0000000124db5edf, pid=5705, tid=0x0000000000001203 Stack: [0x000000030d836000,0x000000030d936000], sp=0x000000030d9354e0, free space=1021k Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)

image

image

saudet commented 8 months ago

Please try to use PointerScope: http://bytedeco.org/news/2018/07/17/bytedeco-as-distribution/

iversionpeng commented 8 months ago

Hello, I would like to ask: Both Mat and MatVector inherit Pointer. There is DeallocatorReference in the Point object. This is to save the memory address. During use, GC occurs, causing the previously created Mat memory to be recycled. Later use of this mat will cause the program to crash. This design Is it reasonable?

saudet commented 8 months ago

Please try to set the "org.bytedeco.javacpp.nopointergc" system property to "true".

iversionpeng commented 8 months ago

Please try to set the "org.bytedeco.javacpp.nopointergc" system property to "true".

We want to understand how javaCp manages off-heap memory so that we can use it more accurately. Can you provide some information for reference?

iversionpeng commented 8 months ago

Please try to set the "org.bytedeco.javacpp.nopointergc" system property to "true".

It is true that there will be no crash when using this method; but why might there be a crash when closinging it? In single thread case

saudet commented 8 months ago

If you need reliability, please don't use GC, use PointerScope. It works just like C++, that's pretty much all you need to know.

iversionpeng commented 8 months ago

If you need reliability, please don't use GC, use PointerScope. It works just like C++, that's pretty much all you need to know.

Thanks a lot!

It is the default way to release memory, Why is the GC method unreliable?

saudet commented 8 months ago

Because it's not designed to track anything else than heap memory.

iversionpeng commented 8 months ago

Because it's not designed to track anything else than heap memory.

Sorry to have bothered you for so long. I try to understand what you mean.

 MatVector contours = new MatVector();
 Mat hierarchy = new Mat();
 findContours(
             securityErodeMat,
             contours,
             hierarchy,
             RETR_CCOMP,
             CHAIN_APPROX_SIMPLE
     );
  Mat[] mats = contours.get();
  for (int i = 0; i < mats.length; ++i) {
         Mat myMat = collect.get(i);
        for (int y = 0; y < 800 * 1600; y++) {
             Scalar currentColor = new Scalar(h, s, v, 0);
 }
            double area = contourArea(myMat, false);
}

When GC is triggered, the DeallocatorReference in MatVector may be recycled. When I use Mat later in contourArea, may I get the wrong data?

saudet commented 8 months ago

Yes, that's possible

iversionpeng commented 8 months ago

Yes, that's possible Thanks a lot! Another question:

image

Where can I get its source code? Not by decompiling the case

saudet commented 8 months ago

You can ignore that library, it's not usually needed.

iversionpeng commented 8 months ago

You can ignore that library, it's not usually needed.

I am verifying the unreliability of relying on Gc to recycle off-heap memory; through the code, I cannot infer what the problem is with relying on GC to recycle off-heap memory, but the phenomenon is that I am using the MatVector object, and then there is a GC log and a Collecting log. Immediately afterwards, the memory space in MatVector was cleared; the code to clean up the off-heap memory relies on GC to trigger MatVector recycling. MatVector is a strong reference and it should not be recycled when I use it, so I feel that it is not triggered by GC, maybe It is the clear method called elsewhere, so I would like to see its underlying implementation; I would like to hear your opinions.

saudet commented 8 months ago

So, what you probably want is the JNI code used for OpenCV and that gets generated at build time: https://github.com/bytedeco/javacpp-presets#build-instructions