我有 2 个vlc
正在运行的实例。一个正在玩。其中一个已暂停(并且大部分已被替换)。
top - 14:25:01 up 23 days, 19:19, 69 users, load average: 2.36, 2.61, 4.19
Tasks: 905 total, 3 running, 894 sleeping, 2 stopped, 6 zombie
%Cpu(s): 11.9 us, 6.5 sy, 0.1 ni, 81.0 id, 0.4 wa, 0.0 hi, 0.0 si, 0.0 st
GiB Mem : 31.2 total, 0.8 free, 27.4 used, 2.9 buff/cache
GiB Swap: 158.3 total, 82.4 free, 75.8 used. 1.5 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
420221 tange 20 0 4066448 601160 28444 S 30.3 1.8 8:55.51 vlc <-- playing
1329863 tange 20 0 2640256 131980 42300 S 0.7 0.4 11:47.28 vlc <-- paused
该视频的分辨率为 1280x720 px 30 fps,当我强制换出时,只有大约 100 MB 被换回。
为什么它们占用如此大量的内存? (600 MB 的播放量似乎很荒谬)我可以更改什么来降低此使用量?
编辑:
我进一步调查了。
下面的数字以千字节为单位,并使用“time -v”进行测量。他们同意“顶”。
这些是常驻的,当我关闭 VLC 时,它们会达到最大值(换句话说:它们不会暂时飙升以找到较低的水平)。
“播放”是指播放完整视频。 “暂停”是指播放前几秒钟,然后暂停,直到内存使用量稳定。
这是“播放 1280x720 且列表中包含 2087 个大视频”的图表(以ps aux
每秒 600 秒的速度测量):
这是“播放 1280x720,列表中包含 0 个大视频”的图表(以ps aux
100 秒的每秒为单位进行测量):
这表明“列表中的 0”的使用量被稍微高估了:RSS 在启动后不久就达到顶峰,并在 15 秒后略有下降。
VSize 始终比 RSS 大 2.3GB。
播放 640x360 且列表中包含 5400 个视频:最大驻留集大小(千字节):1096232
暂停 640x360 且列表中包含 5400 个视频:最大驻留集大小(千字节):1101840
播放 640x360 且列表中有 0 个视频:最大驻留集大小(千字节):333228
暂停 640x360,列表中有 0 个视频:最大驻留集大小(千字节):303792
播放 1280x720 且列表中包含 2087 个大视频:最大驻留集大小(千字节):1273936
暂停 1280x720,列表中包含 2087 个大视频:最大驻留集大小(千字节):1190252
播放 1280x720 且列表中有 0 个视频:最大驻留集大小(千字节):185204
暂停 1280x720,列表中有 0 个视频:最大驻留集大小(千字节):185352
这似乎表明播放列表对 RSS 有巨大的影响,而视频的分辨率却没有。
目前尚不清楚原因。
VLC 清楚地缓存了每个视频的长度:它们的长度慢慢显示在列表中,这解释了如图所示的内存缓慢增加的原因。但长度应该只有几个字节:无论 VLC 做什么,列表中每个视频都会占用 150 kb-500 kb 驻留 RAM。
我发现 200 MB RSS 播放 1280x720 是合理的,但不添加 800 MB RSS 只是将播放列表保留在 RAM 中。
我可以要求 VLC 不要将其缓存在 RAM 中(并仍然保留我的列表)吗?
答案1
这看起来相对合理 - 假设:我们进行软件解码(即,我们不只是将预处理的视频数据发送到 GPU 缓冲区以在硬件中解码),我们正在处理全高清,并且我们正在处理 MPEG4 时代编解码器。
然后,我们需要保留一些易于渲染的帧(即,分解为可以传输到显卡的静态图像格式(或由此处扮演输出角色的任何内容处理)),以允许传输下一帧足够提前,这样播放时就不会卡顿——特别是如果软件解码发生在拥挤的 CPU 上,提前计算一堆帧,将它们写入 RAM,然后希望操作系统在线程或之前重新安排您的时间。通过更改当前显示的图像来更新屏幕的硬件单元已完成。
现在,24 位深度的全高清帧(假设这是使用的纹理格式,但这很可能)大约为 6 MB。考虑到这只是大约 1/4 秒的缓冲区,准备好大约 100 MB 的图像以供传输/位块传输听起来并不浪费。
但是要渲染这些帧,您需要对视频进行解码,视频由许多小的本地内容组成(想想 MPEG-2 及其他内容与 JPEG 没有什么不同,因为它们会处理小图像块,其中一些变换允许某些系数的量化较少,因此压缩),而且还有非常远距离的东西,例如相对运动图(运动补偿,即使在四分之一像素分辨率下),以及相距较远的帧之间的插值 - MPEG-4 AVC (H.264) 使用最多 16 个参考帧来组合以获得新帧。
这意味着单个帧可能需要以不同的方式使用,因此会出现比仍然必要的参考帧更大的中间结果。
现在,我确实同意,应该可以使用小于 600 MB 的此类缓冲区编写解码器;但我猜想(在解码器中没有实际的洞察力)可能存在中间结果,这些结果可以被其他帧重用,因此最好返回到内存池或稍后覆盖。这会使解码内存“膨胀”,但有利于性能。
答案2
我找到了罪魁祸首:
工具 > 首选项 > 显示设置 > 全部 > 播放列表 > 自动准备项目
如果打开此选项,VLC 将读取播放列表中的每个文件并查找视频的长度。显然它还读得更多。
当禁用它时,我的问题消失了(VLC 保持在 200 MB 以下),而当再次启用它时,问题又出现了。
对我来说,这看起来像是 VLC 中的一个错误:为什么保留视频长度会占用超过几兆的总长度?
答案3
我刚刚在 Ubuntu 20.04 上启动了一个 VLC 实例,没有玩任何东西,然后运行pmap PID
查看它映射到内存中的内容。一些有趣的摘录:
000055ac2ba89000 1036K rw--- [ anon ]
00007f616c000000 132K rw--- [ anon ]
00007f616c021000 65404K ----- [ anon ]
00007f6170000000 132K rw--- [ anon ]
00007f6170021000 65404K ----- [ anon ]
00007f6174000000 132K rw--- [ anon ]
00007f6174021000 65404K ----- [ anon ]
.
.
.
00007f617affd000 4K rw--- [ anon ]
00007f617affe000 4K ----- [ anon ]
00007f617afff000 8192K rw--- [ anon ]
00007f617b7ff000 4K ----- [ anon ]
00007f617b800000 8192K rw--- [ anon ]
00007f617c000000 132K rw--- [ anon ]
00007f617c021000 65404K ----- [ anon ]
00007f6180000000 132K rw--- [ anon ]
00007f6180021000 65404K ----- [ anon ]
00007f6184000000 8160K rw--- [ anon ]
00007f61847f8000 57376K ----- [ anon ]
00007f6188000000 132K rw--- [ anon ]
00007f6188021000 65404K ----- [ anon ]
.
.
.
00007f6190000000 65536K rw-s- memfd:pulseaudio (deleted)
00007f6194000000 65536K rw-s- memfd:pulseaudio (deleted)
00007f6198000000 65536K rw-s- memfd:pulseaudio (deleted)
00007f619c000000 65536K rw-s- memfd:pulseaudio (deleted)
.
.
.
total 983604K
鉴于这只是启动 VLC 而不是播放任何事物,我想可以用一个词来准确形容: 奥因克
几乎 1 GB RAM 却什么都不做?你能为这个做什么?少找点东西,嗯,贪婪的内存?