首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >javacpp :内存使用率太高: physicalBytes > maxPhysicalBytes javacpp指针释放程序()

javacpp :内存使用率太高: physicalBytes > maxPhysicalBytes javacpp指针释放程序()
EN

Stack Overflow用户
提问于 2017-11-04 15:30:52
回答 2查看 1.8K关注 0票数 1

我有这样的问题:

org.bytedeco.javacpp.Pointer.deallocator(Pointer.java:562)的物理内存使用率太高: physicalBytes = 1G > maxPhysicalBytes = 1G

long Pointer.physicalBytes正在递增,即使我们释放每个指针对象并调用GC --我一直在监视JVM堆大小,并且它处于控制之下,从来没有超过20%的使用率,这意味着解除分配执行得很好,但出于某种原因,信息(真正的信息)没有传递给Poniter.physicalBytes (它永远不会减少),当错误到达Pointer.maxPhysicalBytes值时,它会错误地抛出错误。

看起来这是几周前修复的(https://github.com/bytedeco/javacpp-presets/issues/423),但即使在获得最新版本的JavaCPP (1.3.3)之后,我仍然有这个问题。

这是我的密码:

代码语言:javascript
复制
import static org.bytedeco.javacpp.opencv_core.cvClearMemStorage;
import static org.bytedeco.javacpp.opencv_core.cvGetSeqElem;
import static org.bytedeco.javacpp.opencv_core.cvPoint;
import static org.bytedeco.javacpp.opencv_core.cvSize;
import static org.bytedeco.javacpp.opencv_imgproc.CV_AA;
import static org.bytedeco.javacpp.opencv_imgproc.cvRectangle;
import static org.bytedeco.javacpp.opencv_objdetect.cvHaarDetectObjects;

import org.bytedeco.javacpp.BytePointer;
import org.bytedeco.javacpp.Pointer;
import org.bytedeco.javacpp.opencv_core;
import org.bytedeco.javacpp.opencv_core.CvMemStorage;
import org.bytedeco.javacpp.opencv_core.CvPoint;
import org.bytedeco.javacpp.opencv_core.CvRect;
import org.bytedeco.javacpp.opencv_core.CvScalar;
import org.bytedeco.javacpp.opencv_core.CvSeq;
import org.bytedeco.javacpp.opencv_core.CvSize;
import org.bytedeco.javacpp.opencv_core.IplImage;
import org.bytedeco.javacpp.opencv_objdetect.CascadeClassifier;
import org.bytedeco.javacpp.opencv_objdetect.CvHaarClassifierCascade;
(...)    

public class ObjectDetection {

    private static CvMemStorage storage = CvMemStorage.create();

    (...)

    public static synchronized Detection detect(IplImage src, Configuration cfg) {

        CvMemStorage storage = CvMemStorage.create();
        CvSeq sign = cvHaarDetectObjects(src, cfg.cascade, storage, cfg.scale, cfg.neighbors, cfg.method.getVal(), cfg.minSize, cfg.maxSize);

        int total_objs = sign.total();

        for (int i = 0; i < total_objs; i++) {
            BytePointer seqElem = cvGetSeqElem(sign, i);
            CvRect r = new CvRect(seqElem);
            CvPoint p1 = cvPoint(r.x(), r.y());
            CvPoint p2 = cvPoint(r.width() + r.x(), r.height() + r.y());
            cvRectangle(src, p1, p2, CvScalar.RED, 2, CV_AA, 0);
            p1.deallocate();
            p2.deallocate();
            r.close();
            r.deallocate();
            seqElem.deallocate();
        }

        BufferedImage img = Images.toBufferedImage(src);

        sign.deallocate();
        src.deallocate();
        storage.deallocate();

        Pointer.deallocateReferences();

        return new Detection(img, total_objs);
    }

    public static class Detection{
        private BufferedImage img;
        private int count;
        private Detection(BufferedImage i, int c){
            img = i; count = c;
        }
        public BufferedImage getImage(){
            return img;
        }
        public int getObjectsCount(){
            return count;
        }
    }


    public static class Configuration{
        private String configName;
        private CascadeClassifier xmlFile;
        private CvHaarClassifierCascade cascade;
        private CvSize minSize; 
        private CvSize maxSize;
        private double scale;
        private int neighbors;
        private Method method;

        private Configuration(String configuration) throws JSONException, IOException{
            configName = configuration;
            JSONObject cfg = new JSONObject(new JSONTokener(new FileReader(new File(configuration+".cfg"))));
            scale = cfg.getDouble("scale");
            neighbors = cfg.getInt("neighbors");
            method = Method.valueOf(cfg.getString("method"));
            int min = cfg.getInt("min_size");
            int max = cfg.getInt("max_size");
            minSize = cvSize(min,min);
            maxSize = cvSize(max,max);
            xmlFile = new CascadeClassifier(configuration+".xml");
            cascade = new CvHaarClassifierCascade(xmlFile.getOldCascade());
        }

        public void dealocate(){
            xmlFile.deallocate();
            cascade.deallocate();
            minSize.deallocate();
            maxSize.deallocate();
            configs.remove(configName);
        }

    }
}

这就是堆栈轨迹:

代码语言:javascript
复制
java.lang.OutOfMemoryError: Physical memory usage is too high: physicalBytes = 1G > maxPhysicalBytes = 1G
org.bytedeco.javacpp.Pointer.deallocator(Pointer.java:576)
org.bytedeco.javacpp.Pointer.init(Pointer.java:121)
org.bytedeco.javacpp.opencv_core.cvPoint(Native Method)
br.com.irisbot.visualrecognition.haarcascade.ObjectDetection.detect(ObjectDetection.java:83)
br.com.irisbot.visualrecognition.haarcascade.ObjectDetectionServlet.doPost(ObjectDetectionServlet.java:71)
javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:475)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:651)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:500)
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:754)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1376)
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.lang.Thread.run(Thread.java:748)
EN

回答 2

Stack Overflow用户

发布于 2018-01-02 17:07:46

事实上,经过很长一段时间来解决内存问题,以及对生产服务的严重需求(在某些请求之后不挂起),我解决了这个问题:

  1. 创建一个独立应用程序(runnable )来执行OpenCV过程,并将结果返回到控制台
  2. 创建一个web服务,将应用程序作为Java进程调用到OS命令行中(这将强制它在单独的JVM中运行)
  3. 捕获进程控制台的结果
  4. 通过web服务返回结果

我同意,你可能会觉得它不那么优雅,但到了一天结束的时候,它会起作用的!一点也不差;-)

票数 1
EN

Stack Overflow用户

发布于 2018-12-24 07:02:08

很可能有些对象没有得到正确的分配。尝试使用PointerScope来更容易地捕获所有的人:http://bytedeco.org/news/2018/07/17/bytedeco-as-distribution/

下面是一个演示如何与CascadeClassifier一起使用它的最小示例:

代码语言:javascript
复制
import org.bytedeco.javacpp.*;
import org.bytedeco.javacv.*;
import static org.bytedeco.javacpp.opencv_core.*;
import static org.bytedeco.javacpp.opencv_imgproc.*;
import static org.bytedeco.javacpp.opencv_objdetect.*;

public class PointerScopeDemo {
    public static void main(String[] args) throws Exception {
        CascadeClassifier classifier = new CascadeClassifier("haarcascade_frontalface_alt2.xml");
        FrameGrabber grabber = FrameGrabber.createDefault(0);
        grabber.start();

        Mat image;
        OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat();
        while ((image = converter.convert(grabber.grab())) != null) {
            try (PointerScope scope = new PointerScope()) {
                RectVector faces = new RectVector();
                classifier.detectMultiScale(image, faces);
                System.out.println(faces.size());
            }
        }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47112338

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档