暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

新优特性之AppCDS / Unified JVM Logging

开源中间件 2021-09-10
953

一 AppCDS


CDS的全称是Class Data Sharing,直译为类数据共享。其作用是在内存或者磁盘上缓存预先处理过的类元数据,在启动时提高应用加载速度,并可以减少内存占用。


这个特性是从Java5开始就有了,最初仅对客户端VM有效,只能应用于系统类和串行GC上。


Java9发布时功能得到了增强,可以用在服务端VM上,也能支持各种GC,包括G1,并行GC等。在OracleJD9K中,还可以通过设置启用商业特性,支持应用类。也就是说,在OpenJdk中以及OracleJdk未做设置时,还只对系统类有效,这样极大的限制了这个特性的应用。



JDK10发布时,这个功能被彻底解锁。通过JEP310实现这个功能AppCDS(Application Class-Data Sharing),这样应用层的类也完全可以用这个特性了。这个特性被称为Oracle第一个开源的商业特性。


1. 运行范例


我们创建一个最简单Java程序Hello.java,并编译

class Hello {

  public static void main (String[] args) {

    System.out.println("Hello Gongzhonghao");

  }

}


使用如下命令,dump出启动时加载的类清单

$ x1/java/javalib/jdk-11/bin/java -Xshare:off -XX:+UseAppCDS -XX:DumpLoadedClassList=hello.lst Hello

OpenJDK 64-Bit Server VM warning: Ignoring obsolete option UseAppCDS; AppCDS is automatically enabled

Hello Gongzhonghao


可以看到AppCDS这个特性已经在Java11中自动可用了,后续我们不再专门设置这个参数

生成的hello.lst文本文件有470行,加载了最常用的Java类清单

$ wc hello.lst 

  470   470 14599 hello.lst

$ head hello.lst 

java/lang/Object

java/lang/String

java/io/Serializable

java/lang/Comparable

....


我们进一步dump出AppCDS的Archive,可以看作是加载后类在内存中的镜像文件

$ x1/java/javalib/jdk-11/bin/java -Xshare:dump -XX:SharedClassListFile=hello.lst  -XX:SharedArchiveFile=hello.jsa Hello

narrow_klass_base = 0x0000000800000000, narrow_klass_shift = 3

Allocated temporary class space: 1073741824 bytes at 0x00000008c0000000

Allocated shared space: 3221225472 bytes at 0x0000000800000000

Loading classes to share ...

Loading classes to share: done.

Rewriting and linking classes ...

Rewriting and linking classes: done

Number of classes 535

    instance classes   =   470

    obj array classes  =    57

    type array classes =     8

...

Dumping symbol table ...

Dumping objects to closed archive heap region ...

Dumping objects to open archive heap region ...

...


如果我们查看Jdk的Hotspot源码,比如在metaspaceShared.cpp中

if (SharedClassListFile == NULL) {

...

class_list_path = class_list_path_str;

} else {

class_list_path = SharedClassListFile; 使用已经存储的CDS list

}


tty->print_cr("Loading classes to share ...");

_has_error_classes = false;

int class_count = preload_classes(class_list_path, THREAD);

if (ExtraSharedClassListFile) {

class_count += preload_classes(ExtraSharedClassListFile, THREAD);

}

tty->print_cr("Loading classes to share: done.");


log_info(cds)("Shared spaces: preloaded %d classes", class_count);


tty->print_cr("Rewriting and linking classes ..."); Rewrite and link classes


link_and_cleanup_shared_classes(CATCH);

tty->print_cr("Rewriting and linking classes: done");


SystemDictionary::clear_invoke_method_table();


VM_PopulateDumpSharedSpace op;

VMThread::execute(&op);

可以看到这个dump过程的实现片段,hello.jsa文件就是存储内存的信息,包括符号表,堆信息等。


后续再次启动这个类时,我们就可以直接使用hello.jsa文件来快速构建加载类和内存信息了

$ x1/java/javalib/jdk-11/bin/java -Xshare:on -XX:SharedArchiveFile=hello.jsa Hello

Hello Gongzhonghao


可以进行运行时长的对比

$ time x1/java/javalib/jdk-11/bin/java Hello

Hello Gongzhonghao


real 0m0.303s

user 0m0.142s

sys 0m0.040s

$ time x1/java/javalib/jdk-11/bin/java -Xshare:on -XX:SharedArchiveFile=hello.jsa Hello

Hello Gongzhonghao


real 0m0.103s

user 0m0.116s

sys 0m0.027s


对于大型应用软件,这个性能优化就很可观了。


2. JDK11目前的能力


在OpenJdk的lib目录下,有一个文件classlist,这个文件就是默认情况下,JDK可以预处理的类。如果我们执行

$ x1/java/javalib/jdk-11/bin/java -Xshare:dump Hello

而不带加载类的清单,则JDK就使用classlist,并把dump出来的classes.jsa文件放在lib/server目录下。因为Java11以及缺省使用AppCDS特性,则后续只要使用

$ x1/java/javalib/jdk-11/bin/java -Xshare:on Hello

Hello Gongzhonghao

就可以,这样对于采用AOT生成的可执行运行环境来说非常方便。


如果要加载的类不在classlist清单上,比如应用自身的类肯定都不在这个列表,就需要采用-XX:DumpLoadedClassList来先生成类加载列表。

不过目前有一个不足就是-XX:DumpLoadedClassList无法列出自己定义的ClassLoader加载的类,而目前主流的框架几乎都使用自行定义的扩展ClassLoader进行加载。


怎么处理这个问题呢?就要通过JDK的另一个新优特性Unified JVM Logging来帮助处理。

$ x1/java/javalib/jdk-11/bin/java -Xshare:on -Xlog:class+load Hello | head

[0.003s][info][class,load] opened: /x1/java/javalib/jdk-11/lib/modules

[0.018s][info][class,load] java.lang.Object source: shared objects file

[0.018s][info][class,load] java.io.Serializable source: shared objects file

[0.018s][info][class,load] java.lang.Comparable source: shared objects file

...

使用-Xlog:class+load,告诉JVM虚拟机打印出类加载的信息,我们会发现绝大多数类已经在shared object file中了。

$ /x1/java/javalib/jdk-11/bin/java -Xshare:on -Xlog:class+load Hello | grep -v "shared object" 

[0.004s][info][class,load] opened: /x1/java/javalib/jdk-11/lib/modules

[0.072s][info][class,load] jdk.internal.loader.URLClassPath$FileLoader source: jrt:/java.base

[0.072s][info][class,load] jdk.internal.loader.URLClassPath$FileLoader$1 source: jrt:/java.base

[0.077s][info][class,load] Hello source: file:/tmp/

Hello Gongzhonghao

只有少数类,是没有在classlist定义,以及我们自己的应用类。


这样给我们的启示,就是我们可以通过-Xlog:class+load,来打印出所有加载类信息


然后使用一个开源工具cl4cds,通过类加载信息,来重新推导出cls文件,这样就得到全面的加载的类清单文件,再进行内存的dump操作。

$ /x1/java/javalib/jdk-11/bin/java -Xshare:on -Xlog:class+load:file=hello.clstrace Hello

$ /x1/java/javalib/jdk-11/bin/java io.simonis.cl4cds hello.clstrace hello_cl4cds.cls


在大型应用,如应用服务器启动时,使用AppCDS特性,可以使启动速度有20%左右的提升。


二 Unified JVM Logging


上面我们提到了Unified JVM Logging(统一JVM日志),这个功能是在Java9通过JEP158加入的。用来统一为JVM中所有的组件打印日志。

比如之前打印GC信息-XX:+PrintGC,如今可以用-Xlog:gc来代替。


借用https://blog.codefx.org/java/unified-logging-with-the-xlog-option/ 一副图来说明


-Xlog:<selectors>:<output>:<decorators>:<output-options>


从几个方面来打印日志

  • Tag标签来表示组件,比如gc,class+load,compiler,thread等等,也可以进行组合

  • Level层级表示日志等级。分为error, warning, info, debug, trace and develop

  • Output表示输入方式,分别是stdout控制台输出,stderr错误输出,file文本文件

  • Decoration定义输出的内容,包括time当前时间,uptime启动时长(可以用毫秒和纳秒表示),pid进程标示,tid线程标示等等


通过以上几个维度的组合定义,我们就可以得到非常详尽的JVM日志信息。对于我们调试程序,排查错误非常有帮助。




数据库
文章转载自 开源中间件,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论

聚圣源银川起名字的地方在哪姓童男人起名水产公司取名起名大全李大宵大猫影视火鸡养殖前景新年快乐祝福根据易经卦象起名金融公司起名寓意好爱你是最好的时光番外怀孕少白洁妇1一18章全文海字起名字好听梓起那些名字晋祠简介哈苏官网孤岂欲卿治经为博士邪翻译为车起名重生逆流崛起带豪男孩起名男宝宝起名字大全男孩起名大全婴儿八字起名大全周姓起名花样明星粤语起名字女孩姓赵咨询公司如何起名起名姓王男孩煤炭能源公司起名大全景姓女孩起名大全赵姓女孩起名字nds中文游戏合集淀粉肠小王子日销售额涨超10倍罗斯否认插足凯特王妃婚姻让美丽中国“从细节出发”清明节放假3天调休1天男孩疑遭霸凌 家长讨说法被踢出群国产伟哥去年销售近13亿网友建议重庆地铁不准乘客携带菜筐雅江山火三名扑火人员牺牲系谣言代拍被何赛飞拿着魔杖追着打月嫂回应掌掴婴儿是在赶虫子山西高速一大巴发生事故 已致13死高中生被打伤下体休学 邯郸通报李梦为奥运任务婉拒WNBA邀请19岁小伙救下5人后溺亡 多方发声王树国3次鞠躬告别西交大师生单亲妈妈陷入热恋 14岁儿子报警315晚会后胖东来又人满为患了倪萍分享减重40斤方法王楚钦登顶三项第一今日春分两大学生合买彩票中奖一人不认账张家界的山上“长”满了韩国人?周杰伦一审败诉网易房客欠租失踪 房东直发愁男子持台球杆殴打2名女店员被抓男子被猫抓伤后确诊“猫抓病”“重生之我在北大当嫡校长”槽头肉企业被曝光前生意红火男孩8年未见母亲被告知被遗忘恒大被罚41.75亿到底怎么缴网友洛杉矶偶遇贾玲杨倩无缘巴黎奥运张立群任西安交通大学校长黑马情侣提车了西双版纳热带植物园回应蜉蝣大爆发妈妈回应孩子在校撞护栏坠楼考生莫言也上北大硕士复试名单了韩国首次吊销离岗医生执照奥巴马现身唐宁街 黑色着装引猜测沈阳一轿车冲入人行道致3死2伤阿根廷将发行1万与2万面值的纸币外国人感慨凌晨的中国很安全男子被流浪猫绊倒 投喂者赔24万手机成瘾是影响睡眠质量重要因素春分“立蛋”成功率更高?胖东来员工每周单休无小长假“开封王婆”爆火:促成四五十对专家建议不必谈骨泥色变浙江一高校内汽车冲撞行人 多人受伤许家印被限制高消费

聚圣源 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化