编译VisualVM源码解决乱码问题
起因
今天在使用VisualVM对测试服务器进行JVM监控的时候,发现所有统计图的横纵坐标都是显示乱码(小方块),即使我的Ubuntu系统使用的是英文语言环境.奇怪的是整个VisualVM软件的其他地方都是显示正常的,不知道是什么原因.
之前在Windows 7时是没有这个问题的,最近刚刚切换系统为Ubuntu 18.04才遇到这个问题.Google了很久似乎别人都没遇到过这个问题. 因为VisualVM是支持多语言的,于是我猜测是VisualVM的在读取国际化文件时出错了,导致对应的数据在格式化显示时除了问题. 带着这个思路,于是想看一下VisualVM的源代码实现.过程
1.找到VisualVM的源代码:
2.定位代码位置,印象中我有一次看到过别人分析VisualVM计算CPU和GC百分比的代码,于是凭着感觉定位到了具体的Java文件: 278行:class CpuViewSupport,其中有个refresh()方法就是用于计算CPU百分比的.按图索骥,追踪到代码:
经过反复调试输出和思考,我认为既然统计图的其他地方都是正常的,说明不是国际化的问题.由于VisualVM的统计图完全是通过Swing绘制的,因此问题应该出在字体上.按照这个思路经过反复运行调试终于找到问题所在. 该类中存在如下2个方法:public static Font smallerFont(Font font) { return new Font(font.getName(), font.getStyle(), font.getSize() - 2);}public static Font boldFont(Font font) { return new Font(font.getName(), Font.BOLD, font.getSize());}
调试输出发现,这2个方法的参数font值为
:java.awt.Font[family=Source Code Pro,name=Source Code Pro,style=plain,size=11]这时我想起之前出现过在IDEA中设置字体为"Source Code Pro"总是设置不成功,这更加让我确定导致VisualVM统计图乱码的问题一定在这里,修改为:
public static Font smallerFont(Font font) { //return new Font(font.getName(), font.getStyle(), font.getSize() - 2); return new Font("Inconsolata Medium", font.getStyle(), font.getSize() - 2);}public static Font boldFont(Font font) { //return new Font(font.getName(), Font.BOLD, font.getSize()); return new Font("Inconsolata Medium", Font.BOLD, font.getSize());}
其中,确保字体"Inconsolata Medium"在系统中存在.
使用确保已经存在的字体替换后,重新编译运行,显示正常.3.编译和运行VisualVM
在开始编译和运行VisualVM源码之前,需要先安装ant: 参照 中的描述步骤即可编译并运行VisualVM.结论
1.借助如下几个chrome插件,对于查看github源码非常有帮助:
octotree Sourcegraph 2.其实,当我确认是字体原因导致之后,安装主题工具:gnome-tweak-tools(sudo apt-get install gnome-tweak-tool)重新设置系统字体即可解决该问题,根本不用修改源代码.只不过这也是一种解决问题的思路,更加深了对VisualVM原理的理解,也不是什么坏事.【参考】
手动编译VisualVM源码