2017-11-04 5 views
0

私はこの問題を持っています:のJavaのOutOfMemoryError:メモリ使用量が高すぎる:physicalBytes> maxPhysicalBytes javacppポインタメモリ解放()

java.lang.OutOfMemoryErrorを:物理メモリの使用率が高すぎる:physicalBytes = 1G> maxPhysicalBytes = org.bytedeco.javacpp.Pointer.deallocatorで1G(Pointer.java:562)

長いPointer.physicalBytesは、我々はすべての単一のポインタオブジェクトの割り当てを解除し、GCを呼び出す場合にも増加している - 私は、JVMのヒープサイズを監視してきたし、それは制御下にあり、決して20%を越える使用は決して解約されないが、何らかの理由で情報(本物)がPに渡されていないことを意味する(減少れることは決してありません)oniter.physicalBytes、それはこれが(https://github.com/bytedeco/javacpp-presets/issues/423)数週間前に修正されましたが、私はまだであっても、この問題が生じていますようにPointer.maxPhysicalBytes

の値が見える達したとき、それは誤ってエラーをスローしますJavaCPPの最新バージョン(1.3.3)

を取得した後、これが私のコードです:

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); 
     } 

    } 
} 

、これはスタックトレースです:

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) 

答えて

0
  1. は、スタンドアローンのアプリを作成:は、実際には、長い時間がメモリの問題に苦しんで、そして深刻な要件を(一部の要求の後にハングアップしません)生産サービスを持つようにした後、私は問題を回避働いていましたOpenCVプロシージャを実行して結果をコンソールに返す
  2. OSコマンドラインでアプリケーションをJavaプロセスとして呼び出すWebサービスを作成する(別のJVMで強制実行する)
  3. プロセスのコンソールから結果を取得する
  4. Webサービスを通じて結果を返す

あなたはそれほどエレガントではないかもしれませんが、私は同意しますが、その日の終わりにはうまくいきます!とても悪くはありません;-)

関連する問題