【问题标题】:Memory Consumption is always increasing in Humble-VideoHumble-Video 中的内存消耗一直在增加
【发布时间】:2017-03-19 10:32:16
【问题描述】:

我一直在直播项目中使用humble-video 将flv 转换为mp4。我已经意识到,使用 top 命令查看时,java 进程(其中正在运行简陋的视频代码)的内存使用量总是在增加。

之后,我更改了谦虚视频的演示源代码,并将segmentFile function 置于无限循环中,当使用 top 命令查看时,进程的内存使用量再次总是增加。它超过 2.5GiB 并且已经运行了大约 30 分钟。

我希望进程的内存消耗保持稳定在 40-50MB 之间,而不是一直增加。

你对此有什么想法吗?

【问题讨论】:

    标签: java video memory-leaks ffmpeg java-native-interface


    【解决方案1】:

    我已经解决了这个问题。

    问题是垃圾收集器没有清除 WeakReferences,因此 JNIMemoryManager 不会删除本机对象。在每次迭代后调用 System.gc() 会有所帮助,但这不是确切的解决方案。

    解决方案是在每次迭代结束时调用 delete()。在执行过程中创建了一些您可能没有预料到的对象,因此请查看使用JNIMemoryManager.getMgr().dumpMemoryLog(); 创建的对象并查看使用JNIMemoryManager.getMgr().getNumPinnedObjects(); 创建的对象有多少

    segmentFile 函数的最后状态如下,在 15 分钟结束时内存消耗仍然保持在 80 MiB 左右。

     private void segmentFile(String input, String output, int hls_start,
          int hls_time, int hls_list_size, int hls_wrap, String hls_base_url,
          String vFilter,
          String aFilter) throws InterruptedException, IOException {
    
        JNIMemoryManager.getMgr().setMemoryDebugging(true);
    
    
        Demuxer demuxer = Demuxer.make();
    
        demuxer.open(input, null, false, true, null, null);
    
        // we're forcing this to be HTTP Live Streaming for this demo.
        Muxer muxer = Muxer.make(output, null, "hls");
        muxer.setProperty("start_number", hls_start);
        muxer.setProperty("hls_time", hls_time);
        muxer.setProperty("hls_list_size", hls_list_size);
        muxer.setProperty("hls_wrap", hls_wrap);
        if (hls_base_url != null && hls_base_url.length() > 0)
          muxer.setProperty("hls_base_url", hls_base_url);
    
        MuxerFormat format = MuxerFormat.guessFormat("mp4", null, null);
    
        /**
         * Create bit stream filters if we are asked to.
         */
        BitStreamFilter vf = vFilter != null ? BitStreamFilter.make(vFilter) : null;
        BitStreamFilter af = aFilter != null ? BitStreamFilter.make(aFilter) : null;
    
        int n = demuxer.getNumStreams();
        DemuxerStream[] demuxerStreams = new DemuxerStream[n];
        Decoder[] decoders = new Decoder[n];
        List<MuxerStream> muxerStreamList = new ArrayList();
        for(int i = 0; i < n; i++) {
          demuxerStreams[i] = demuxer.getStream(i);
          decoders[i] = demuxerStreams[i].getDecoder();
          Decoder d = decoders[i];
    
          if (d != null) {
            // neat; we can decode. Now let's see if this decoder can fit into the mp4 format.
            if (!format.getSupportedCodecs().contains(d.getCodecID())) {
              throw new RuntimeException("Input filename (" + input + ") contains at least one stream with a codec not supported in the output format: " + d.toString());
            }
            if (format.getFlag(MuxerFormat.Flag.GLOBAL_HEADER))
              d.setFlag(Coder.Flag.FLAG_GLOBAL_HEADER, true);
            d.open(null, null);
            muxerStreamList.add(muxer.addNewStream(d));
          }
        }
        muxer.open(null, null);
    
        n = muxer.getNumStreams();
        MuxerStream[] muxerStreams = new MuxerStream[n];
        Coder[] coder = new Coder[n];
        for (int i = 0; i < n; i++) {
            muxerStreams[i] = muxer.getStream(i);
            if (muxerStreams[i] != null) {
                coder[i] = muxerStreams[i].getCoder();
            }
        }
    
        MediaPacket packet = MediaPacket.make();
    
        while(demuxer.read(packet) >= 0) {
          /**
           * Now we have a packet, but we can only write packets that had decoders we knew what to do with.
           */
          final Decoder d = decoders[packet.getStreamIndex()];
          if (packet.isComplete() && d != null) {
            // check to see if we are using bit stream filters, and if so, filter the audio
            // or video.
            if (vf != null && d.getCodecType() == Type.MEDIA_VIDEO)
              vf.filter(packet, null);
            else if (af != null && d.getCodecType() == Type.MEDIA_AUDIO)
              af.filter(packet, null);
    
            muxer.write(packet, false);
    
          }
        }
    
    
    
        // It is good practice to close demuxers when you're done to free
        // up file handles. Humble will EVENTUALLY detect if nothing else
        // references this demuxer and close it then, but get in the habit
        // of cleaning up after yourself, and your future girlfriend/boyfriend
        // will appreciate it.
    
        muxer.close();
        demuxer.close();
    
        muxer.delete();
        demuxer.delete();
        packet.delete();
        format.delete();
        vf.delete();
    
        muxer = null;
        demuxer = null;
        packet = null;
        format = null;
        vf = null;
    
        for (int i=0; i < muxerStreams.length; i++) {
            if (muxerStreams[i] != null) {
                muxerStreams[i].delete();
                muxerStreams[i] = null;
            }
            if (coder[i] != null) {
                coder[i].delete();
                coder[i] = null;
            }
        }
    
        for (int i=0; i < demuxerStreams.length; i++) {
            if (demuxerStreams[i] != null) {
                demuxerStreams[i].delete();
                demuxerStreams[i] = null;
            }
            if (decoders[i] != null) {
                decoders[i].delete();
                decoders[i] = null;
            }
        }
    
        for (Iterator iterator = muxerStreamList.iterator(); iterator.hasNext();) {
            MuxerStream muxerStream = (MuxerStream) iterator.next();
            if (muxerStream != null) {
                muxerStream.delete();
                muxerStream = null;
            }
        }
        muxerStreamList.clear();
        muxerStreamList = null;
    
        System.out.println("number of alive objects:" + JNIMemoryManager.getMgr().getNumPinnedObjects());
    
    
      }
    

    【讨论】:

    • 为了将来参考,Humble Video 有一个工具可以启动一个线程来强制收集(但默认情况下不会启动它)。见:io.humble.ferry.JNIMemoryManager.startCollectionThread()
    猜你喜欢
    • 1970-01-01
    • 2021-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多