内存溢出, 高级程序员的必修课
而且往往是伴随着大压力并发一起来
下面是一个实例
线程实例在另一个贴子里有讲, 这个实例线程上没问题, 就没有截图了
把JVM设置在最大内存64M, 好快速产生瓶颈
[img]http://dl2.iteye.com/upload/attachment/0117/7599/18e76dc0-5dd1-37d1-9c63-107b97ba11d2.png[/img]
运行程序, 打开jconsole监控
[img]http://dl2.iteye.com/upload/attachment/0117/7601/378f2793-e653-3ae2-bfda-5a7629344533.png[/img]
查看内存
[img]http://dl2.iteye.com/upload/attachment/0117/7603/24ef8b51-e143-3980-b2be-b96cd1b859ab.png[/img]
打开jmeter, 100个线程, 循环100次, 由于前面调低了内存, 所以不需要跑太猛, 而且我的是notebook, 4G内存, win7, mysql, netbean等一堆后台, 资源有限
[img]http://dl2.iteye.com/upload/attachment/0117/7605/28634dea-e660-39a6-86c6-4a17ac90d690.png[/img]
[img]http://dl2.iteye.com/upload/attachment/0117/7607/a5cea32c-535e-3117-9a82-ae82aa7b4a7d.png[/img]
[img]http://dl2.iteye.com/upload/attachment/0117/7613/7f315abb-b322-3a49-a53a-3ea54cd4e9df.png[/img]
[img]http://dl2.iteye.com/upload/attachment/0117/7611/55408f89-26d6-3b26-9b5f-36ad9d5fa467.png[/img]
[img]http://dl2.iteye.com/upload/attachment/0117/7633/3225f23b-d388-393a-9d8a-6d7bc08f5ca0.png[/img]
100个线程, 循环100次跑下来, 内存爆了
JVM尝试了很多次GC, 但没办法
程序陷入GC死循环, 进入假死状态, 再过一会就直接out of memory
注意看曲线直接上升的势头, 多美妙
-----一轮蛋疼的调试, 过程略过-----
下面是弄好后的结果
[img]http://dl2.iteye.com/upload/attachment/0117/7615/522272c7-871c-3fc5-9cd2-e4f5a4bdd994.png[/img]
再次打开jconsole
[img]http://dl2.iteye.com/upload/attachment/0117/7617/89081992-0534-360d-a576-13c020f88080.png[/img]
清空jmeter
[img]http://dl2.iteye.com/upload/attachment/0117/7619/2f87efa8-fa05-3263-aea7-7d7f156504ac.png[/img]
100个线程, 循环100次跑完
[img]http://dl2.iteye.com/upload/attachment/0117/7621/664fe16c-546e-3824-a1c1-0cdc042a457d.png[/img]
内存才用了25m, 有升有降的曲线说明内存很健康
[img]http://dl2.iteye.com/upload/attachment/0117/7623/09570636-858f-3280-bbab-1f27ec18e68f.png[/img]
执行下GC, OLD GEN 果断下降, 至此, 内存溢出问题解决
-----下面是代码分析-----
[img]http://dl2.iteye.com/upload/attachment/0117/7627/3e18bc33-7bb5-38b6-af15-f44014ffca69.png[/img]
这是原代码, 作用是抽取netty的post请求参数
[img]http://dl2.iteye.com/upload/attachment/0117/7629/cd6eb69f-f0a5-349c-a417-48fdca6693c0.png[/img]
这是分析解决后的代码, 这种事情, 往往1,2天的调试下来, 就是1,2句代码的事
当然这也从另一方面证明了该程序员的代码质量是很好的
[img]http://dl2.iteye.com/upload/attachment/0117/7631/691b5da5-73af-3042-ac7c-8ddafc9b4e62.png[/img]
这是"坑货" HttpDataFactory,
为什么不把HttpDataFactory放在函数里呢
这是出于性能考虑, 为了减少初始化的次数, 把它放外面, 符合资深程序员的思维
只是一方面对API不熟悉, 另一方面忽略了长期持有的情况
而且往往是伴随着大压力并发一起来
下面是一个实例
线程实例在另一个贴子里有讲, 这个实例线程上没问题, 就没有截图了
把JVM设置在最大内存64M, 好快速产生瓶颈
[img]http://dl2.iteye.com/upload/attachment/0117/7599/18e76dc0-5dd1-37d1-9c63-107b97ba11d2.png[/img]
运行程序, 打开jconsole监控
[img]http://dl2.iteye.com/upload/attachment/0117/7601/378f2793-e653-3ae2-bfda-5a7629344533.png[/img]
查看内存
[img]http://dl2.iteye.com/upload/attachment/0117/7603/24ef8b51-e143-3980-b2be-b96cd1b859ab.png[/img]
打开jmeter, 100个线程, 循环100次, 由于前面调低了内存, 所以不需要跑太猛, 而且我的是notebook, 4G内存, win7, mysql, netbean等一堆后台, 资源有限
[img]http://dl2.iteye.com/upload/attachment/0117/7605/28634dea-e660-39a6-86c6-4a17ac90d690.png[/img]
[img]http://dl2.iteye.com/upload/attachment/0117/7607/a5cea32c-535e-3117-9a82-ae82aa7b4a7d.png[/img]
[img]http://dl2.iteye.com/upload/attachment/0117/7613/7f315abb-b322-3a49-a53a-3ea54cd4e9df.png[/img]
[img]http://dl2.iteye.com/upload/attachment/0117/7611/55408f89-26d6-3b26-9b5f-36ad9d5fa467.png[/img]
[img]http://dl2.iteye.com/upload/attachment/0117/7633/3225f23b-d388-393a-9d8a-6d7bc08f5ca0.png[/img]
100个线程, 循环100次跑下来, 内存爆了
JVM尝试了很多次GC, 但没办法
程序陷入GC死循环, 进入假死状态, 再过一会就直接out of memory
注意看曲线直接上升的势头, 多美妙
-----一轮蛋疼的调试, 过程略过-----
下面是弄好后的结果
[img]http://dl2.iteye.com/upload/attachment/0117/7615/522272c7-871c-3fc5-9cd2-e4f5a4bdd994.png[/img]
再次打开jconsole
[img]http://dl2.iteye.com/upload/attachment/0117/7617/89081992-0534-360d-a576-13c020f88080.png[/img]
清空jmeter
[img]http://dl2.iteye.com/upload/attachment/0117/7619/2f87efa8-fa05-3263-aea7-7d7f156504ac.png[/img]
100个线程, 循环100次跑完
[img]http://dl2.iteye.com/upload/attachment/0117/7621/664fe16c-546e-3824-a1c1-0cdc042a457d.png[/img]
内存才用了25m, 有升有降的曲线说明内存很健康
[img]http://dl2.iteye.com/upload/attachment/0117/7623/09570636-858f-3280-bbab-1f27ec18e68f.png[/img]
执行下GC, OLD GEN 果断下降, 至此, 内存溢出问题解决
-----下面是代码分析-----
[img]http://dl2.iteye.com/upload/attachment/0117/7627/3e18bc33-7bb5-38b6-af15-f44014ffca69.png[/img]
这是原代码, 作用是抽取netty的post请求参数
[img]http://dl2.iteye.com/upload/attachment/0117/7629/cd6eb69f-f0a5-349c-a417-48fdca6693c0.png[/img]
这是分析解决后的代码, 这种事情, 往往1,2天的调试下来, 就是1,2句代码的事
当然这也从另一方面证明了该程序员的代码质量是很好的
[img]http://dl2.iteye.com/upload/attachment/0117/7631/691b5da5-73af-3042-ac7c-8ddafc9b4e62.png[/img]
这是"坑货" HttpDataFactory,
为什么不把HttpDataFactory放在函数里呢
这是出于性能考虑, 为了减少初始化的次数, 把它放外面, 符合资深程序员的思维
只是一方面对API不熟悉, 另一方面忽略了长期持有的情况