Qt字体占用内存过大解决方案
(3)两者区别之三为,繁体软件所使用的主板拥有扩展芯片,分析是否因扩展芯片及扩展芯片程序,导致占用CPU使用率,进而导致占用内存。因GUI应用程序,为了方便显示字符,会提前将字体导入程序缓冲区中,并在程序的堆区中创建字体及渲染,且因繁体的复杂程度比简体的高,导致堆区内存占用过大。解决方式2,使用字体度量与渲染复杂度更小的繁体字库,重新查找字体文件,最终找到一个TaibeiHeiti.ttf字体文件
近期遇到一个问题,同一个软件运行在不同的系统固件上,竟然有一个出现无法使用管道的情况。排查问题原因为运行内存不足,导致系统无法分配足够的内存来执行命令或创建管道。
两个软件一个用于简体,一个用于繁体。
发现简体软件可正常使用管道对Linux系统使用命令。将两者的区别进行比较,并排查问题。
(1)两者区别之一为,繁体软件因存在较多功能,故开启线程较多。将功能关闭后,内存仍然不足以用于创建管道去执行命令。故分析不为线程过多导致的问题。
(2)两者区别之二为,繁体软件存在繁体字库,导致导入软件之后,占用内存较多。将字体文件裁剪,由5M裁剪为400KB后,再导入软件中,内存仍然不足。
(3)两者区别之三为,繁体软件所使用的主板拥有扩展芯片,分析是否因扩展芯片及扩展芯片程序,导致占用CPU使用率,进而导致占用内存。但经分析,占用CPU使用率,与占用内存过大关系不强,且在没有扩展芯片的主板上运行繁体程序,内存仍然占用过大。
(4)两者区别之四为,繁体软件所使用的繁体翻译及繁体字典文件占用内存,将这两个删除打包为执行软件后,运行程序仍然占用内存过多。
后查阅资料,深入分析问题。最终还是将问题聚焦在繁体字体文件上。因GUI应用程序,为了方便显示字符,会提前将字体导入程序缓冲区中,并在程序的堆区中创建字体及渲染,且因繁体的复杂程度比简体的高,导致堆区内存占用过大。
该问题排查的步骤为,使用pidof ut_monitor指令,获取到应用程序的pid,并依据pid,使用cat /proc/pid/smaps,查看进程的内存映射信息,获取到应用程序进程中堆区占用情况。后将系统固件中的字体文件删除,重新运行程序,堆区占用明显缩小一半以上。并查阅资料得知:繁体字体比简体字体的字体度量与渲染复杂度更大,字体不仅仅是静态的图形文件,它们包含复杂的指令和度量信息。比如:
(1)字形数量、轮廓复杂度(曲线指令多少)可能不同,一个字体可能为某些字符提供了更复杂的矢量轮廓。框架在解析这些轮廓时,可能会在内存中创建更复杂的数据结构(如图形路径对象),这些对象分配在堆上。
(2)字体的度量信息(如字宽、字高、间距、基线等)不同。当应用程序进行文本布局计算时(例如计算一个文本框需要多大空间、如何换行),如果字体度量更复杂或计算方式不同,可能会生成更多临时的或永久的布局对象,占用堆内存。
(3)为了性能,UI框架会将渲染后的字形缓存为位图。如果繁体字的默认字号更大、或字形更复杂,每个缓存位图所占用的内存就会更大。即使显示相同的文字数量,缓存这些字形所需的堆内存也会显著增加。
解决方式1,禁用Hinting及抗锯齿,牺牲渲染字体所需的内存。但该方式不可行,因在应用程序中进行,禁用Hinting及抗锯齿进一步加重了内存占用。
解决方式2,使用字体度量与渲染复杂度更小的繁体字库,重新查找字体文件,最终找到一个TaibeiHeiti.ttf字体文件,该文件字体度量与渲染复杂度更小,运用在程序上,明显内存占用减低。
更多推荐
所有评论(0)