线上一个字体工具引发的内存泄漏问题

这个是怎么发现的呢,虽然没有引发OOM,但是自从我接手这个项目以后,前期都是改bug,写新需求,最近疫情在家,并且新做的小程序等待审核的期间,发现了个线上问题;发现每隔一段时间,一般是一两周,线上的堆内存就逐渐增大,虽然很缓慢的增长,但是使用jmap -heap命令查看到老年代也是越来越大,以往的gc没有起作用,正常来说内存占用应该是从部署逐步上升到保持一个稳定的水平。

1.使用命令获取jvm内存dump:

jmap -dump:format=b,file=10339.hprof 10339

 2.使用工具自动分析大概率有问题的内存占用线程及实例:

 大概看到了是这个DIsposer中的Hashtable占用了很大的内存;

3.查看按照内存占用降序的实例数:

 

 其实现在通过其中的内容已经看到了一些端倪,就是TrueTypeFont的其中字符串变量是HYHeiFangW,这个是以前开发人员封装的字体工具中使用到的;

 4.查看代码:

static  Font registerFont(String fontFileName,int style, float fontSize){
        if(fontFileName == null){
            fontFileName = HYHFW;
        }

        Font font = null;
        try {
            URL url =  AbstractPenAndBackground.class.getClassLoader().getResource(fontFileName);
            File fontFile = new File(url.getFile());
            font = Font.createFont(Font.TRUETYPE_FONT, fontFile).deriveFont(style,fontSize);
            //GraphicsEnvironment ge = GraphicsEnvironment .getLocalGraphicsEnvironment();
            //ge.registerFont(font);
        } catch (FontFormatException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return font;
    }

注释的代码就是引发内存泄漏的地方,跟进去代码可以看到:

sun.font.SunFontManager#registerFont方法:

 AppContext var8 = AppContext.getAppContext();
                        var6 = (Hashtable)var8.get(regFamilyKey);
                        var7 = (Hashtable)var8.get(regFullNameKey);
                        if (var6 == null) {
                            var6 = new Hashtable();
                            var7 = new Hashtable();
                            var8.put(regFamilyKey, var6);
                            var8.put(regFullNameKey, var7);
                        }

                        this.fontsAreRegisteredPerAppContext = true;
                    }

                    Font2D var12 = FontUtilities.getFont2D(var1);
                    int var9 = var12.getStyle();
                    FontFamily var10 = (FontFamily)var6.get(var4);
                    if (var10 == null) {
                        var10 = new FontFamily(var1.getFamily(var3));
                        var6.put(var4, var10);
                    }

每次调用字体工具方法,都会将新的Font实例放到静态Hashtable中;解决方法其实就是要么取消这个操作,要么将Font也单例化;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值