GStreamer версия: 1.14.4
В моем исходном приложении одновременно воспроизводилось несколько видео (началось с 300 МБ и увеличилось до 1 ГБ после нескольких перезапусков). Они должны быть перезапущены (разархивировать весь конвейер и создать заново) каждые N минут. После 3-го или 4-го перезапуска потребление памяти увеличилось до 6-7 ГБ и снова уменьшилось до 1 ГБ. Это случилось несколько раз. Так что это не типичная утечка памяти, но я не знаю, почему она началась с 300 МБ, увеличилась до 1 ГБ и колебалась между 6-7 и 1 ГБ.
Поэтому я решил создать 2 простых теста.
1-й тест:
То, что я тестировал: простое видео, длина 114,8 МБ и продолжительность почти 5 минут.
В чем была проблема: использование памяти начинается с 62,2 МБ и увеличивается до 88 МБ после 1-го воспроизведения. Когда видео было перезагружено и конвейер перезапущен (повторно обработан и создан заново), использование памяти осталось 88 МБ и продолжало увеличиваться до 105 МБ, где оно оставалось стабильным в течение оставшегося времени тестирования.
auto app = Gtk::Application::create("org.gtkmm.app");
Gtk::Window w;
gst_init(NULL, NULL);
Glib::signal_timeout().connect_seconds([]()
{
auto pipeline = gst_parse_launch("playbin uri=file:///path/to/150.mp4", NULL);
gst_element_set_state (pipeline, GST_STATE_PLAYING);
auto bus = gst_element_get_bus (pipeline);
auto msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, (GstMessageType)(GST_MESSAGE_ERROR | GST_MESSAGE_EOS));
if (msg != NULL)
gst_message_unref (msg);
gst_object_unref (bus);
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
return true;
}, 5);
return app->run(w);
2-й тест связан даже не с конвейером, а с GstDiscoverer, который я также использовал в своем исходном приложении.
Что я тестировал: простой плагин GstDiscoverer
В чем была проблема: объем памяти начался с 19,2 МБ и увеличился до 100 МБ после нескольких обнаружений, где оставался стабильным в течение оставшегося времени тестирования;
auto app = Gtk::Application::create("org.gtkmm.app");
Gtk::Window w;
gst_init(NULL, NULL);
Glib::signal_timeout().connect_seconds([](){
auto discoverer = gst_discoverer_new(5 * GST_SECOND, nullptr);
auto info = gst_discoverer_discover_uri(discoverer, "file:///path/to/150.mp4", nullptr);
gst_discoverer_info_unref(info);
g_object_unref(discoverer);
return true;
}, 5);
return app->run(w);
Вывод: это не настоящая утечка памяти, но я хочу знать, почему она постоянно увеличивает память до некоторой "магической границы". В исходном приложении оно было еще более странным, поскольку оно колебалось между 1 ГБ и 6-7 ГБ, несмотря на то, что все ресурсы не были переброшены.
Возможно, GStreamer использует некоторый внутренний пул или кеш, который не освобождается даже после отмены конвейера. Есть предложения?