Skip to content

native memory still exists after Pipeline.close #248

Closed

Description

@JamesTangChengDu
No description provided.

Activity

  1. neilcsmith-net commented on Jan 18, 2022

    @neilcsmith-net
    Member

    Please provide contextual information and a code example that demonstrates this problem, or this issue will be closed. This is not a general problem, so is being triggered by something specific to your usage or code. Thanks.

  2. JamesTangChengDu commented on Jan 18, 2022

    @JamesTangChengDu
    Author

    Thanks for your reply, I will upload a demo code later.

  3. JamesTangChengDu commented on Jan 18, 2022

    @JamesTangChengDu
    Author

    1, I execute the following command to run my demo, The heap capacity of the jvm is 3M.
    java -Xmx3M -verbose:gc -jar /mnt/tangjun/demo/vdm-0.0.1.jar

    2, The source code of my program is as follows: (where the keepAlive function is just to prevent the program from exiting)
    /**

    • the main entry of GStreamer Demo.
      */
      public class App {
      private static final int GST_VERSION_MAJOR = 1;
      private static final int GST_VERSION_MINOR = 10;

      /**

      • CM App instance.
        */
        public App() {
        Gst.init(new Version(GST_VERSION_MAJOR, GST_VERSION_MINOR));
        //testGst();

        keepAlive();
        Gst.deinit();
        }

      private void testGst() {
      final Pipeline mPipeline = new Pipeline();

       String url = "rtsp://admin:ThunderSoft88@192.168.10.43/onvif-media/media.amp?profile=profile_1_h264&sessiontimeout=60&streamtype=unicast";
      
       Element src = ElementFactory.make("rtspsrc", "src");
       src.set("location", url);
       src.set("latency", 0);
       src.set("ntp-time-source", 3);
      
       final Element sink = ElementFactory.make("fakesink", "sink");
      
      
       mPipeline.addMany(src, sink);
      
       src.connect(new Element.PAD_ADDED() {
           @Override
           public void padAdded(Element element, Pad pad) {
               Pad sinkPad = sink.getStaticPad("sink");
               try {
                   pad.link(sinkPad);
      
                   System.out.println("Pad " + pad.getName() + " link to Pad"
                           + sinkPad.getName());
               } catch (PadLinkException ex) {
                   System.out.println("Pad link failed : " + ex.getLinkResult());
               }
           }
       });
      
       final String gstCmd = "rtspsrc location="+url+" latency=0 ntp-time-source=3 ! faksink";
      
       System.out.println("demo gstreamer play: " + gstCmd);
       mPipeline.play();
      
       final int buffer_cacher_waiting_time1 = 1000 * 10; // in milliseconds
       new java.util.Timer().schedule(new java.util.TimerTask() {
           @Override
           public void run() {
               System.out.println("demo gstreamer stop: "+ gstCmd);
               mPipeline.stop();
      
               System.out.println("demo gstreamer close: "+ gstCmd);
               mPipeline.close();
           }
       }, buffer_cacher_waiting_time1);
      

      }

      /**

      • keep main thread alive.
        */
        public void keepAlive() {
        synchronized (this) {
        try {
        this.wait();
        } catch (InterruptedException ex) {
        ex.printStackTrace();
        }
        }
        }

      /**

      • The main function for CM.

      */
      public static void main(String[] args) {
      // keep main thread alive
      App main = new App();
      }
      }

    3, Below I have 3 test results:
    3.1, when the testGst function is commented out in the code, top RES=32.9m. ("top RES=32.9m" means that after executing top command, the value of RES is 32.9M)
    3.2, When the testGst function is executed in the code and mPipeline.play() is run, but it has not run to mPipeline.stop, top RES=44.9m
    3.3, When 3.2 continues to run, and after mPipeline.stop and mPipeline.close are executed, top RES=46.9m, and the memory does not decrease but increases.
    I'm guessing the memory should go back to around "top RES=32.9m" after step 3, right?

  4. JamesTangChengDu commented on Jan 18, 2022

    @JamesTangChengDu
    Author

    The code typesetting is a bit unfriendly, I rearranged it as follows for your convenience:

    public class App {

    private static final int GST_VERSION_MAJOR = 1;
    private static final int GST_VERSION_MINOR = 10;
    
    public App() {
        Gst.init(new Version(GST_VERSION_MAJOR, GST_VERSION_MINOR));
        testGst();
    
        keepAlive();
        Gst.deinit();
    }
    
    private void testGst() {
        final Pipeline mPipeline = new Pipeline();
    
        String url = "rtsp://admin:ThunderSoft88@192.168.10.43/onvif-media/media.amp?profile=profile_1_h264&sessiontimeout=60&streamtype=unicast";
    
        Element src = ElementFactory.make("rtspsrc", "src");
        src.set("location", url);
        src.set("latency", 0);
        src.set("ntp-time-source", 3);
    
        final Element sink = ElementFactory.make("fakesink", "sink");
    
    
        mPipeline.addMany(src, sink);
    
        src.connect(new Element.PAD_ADDED() {
            @Override
            public void padAdded(Element element, Pad pad) {
                Pad sinkPad = sink.getStaticPad("sink");
                try {
                    pad.link(sinkPad);
    
                    System.out.println("Pad " + pad.getName() + " link to Pad"
                            + sinkPad.getName());
                } catch (PadLinkException ex) {
                    System.out.println("Pad link failed : " + ex.getLinkResult());
                }
            }
        });
    
        final String gstCmd = "rtspsrc location="+url+" latency=0 ntp-time-source=3 ! faksink";
    
        System.out.println("demo gstreamer play: " + gstCmd);
        mPipeline.play();
    
        final int buffer_cacher_waiting_time1 = 1000 * 10; // in milliseconds
        new java.util.Timer().schedule(new java.util.TimerTask() {
            @Override
            public void run() {
                System.out.println("demo gstreamer stop: "+ gstCmd);
                mPipeline.stop();
    
                System.out.println("demo gstreamer close: "+ gstCmd);
                mPipeline.close();
            }
        }, buffer_cacher_waiting_time1);
    }
    
    public void keepAlive() {
        synchronized (this) {
            try {
                this.wait();
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }
    
    public static void main(String[] args) {
        App main = new App();
    }
    

    }

  5. JamesTangChengDu commented on Jan 18, 2022

    @JamesTangChengDu
    Author

    Looking forward to your reply, thank you very much.

  6. neilcsmith-net commented on Jan 18, 2022

    @neilcsmith-net
    Member

    There are a number of problems in your code, I'm not sure your assumption that all memory will be released is necessarily correct, and it's possible you're seeing some interaction with #244 caused by calling close() off the GStreamer event thread or directly after stop().

    A few pointers -

    • Always store the pipeline in a field.
    • Use Gst.main() and Gst.quit() to keep alive.
    • Try to always interact with GStreamer, particularly after starting a pipeline, using Gst.executor() - that will correctly interleave with bus messages, and supports scheduling already (no need for Timer).
    • Don't call close() immediately after stop(). Use Gst.invokeLater() if you want to do this.
    • You don't need to explicitly dispose of anything, but if you do you need to make sure that other things that might interact with the same element have completed.
    • Never call Gst.deinit()

    Try looking at the structure of the various examples in https://github.com/gstreamer-java/gst1-java-examples

    Moving this into discussions. I don't believe it's a sign of a native memory leak.

  7. locked and limited conversation to collaborators on Jan 18, 2022
  8. converted this issue into a discussion #249 on Jan 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions