Jdk调优实战

堆外内存导致溢出错误

        例如一个2G内存的物理机,将1.6G划入java虚拟机中,这样物理机能够使用的直接内存最多只有0.4G,虽然java虚拟机会对直接内存进行回收,但是直接内存满后无法像虚拟机内存那样通知垃圾回收器进行回收,因此直接内存满后再写入写的数据会导致堆外内存泄漏

        解决方案

        调整虚拟机堆的大小,对直接内存进行池化处理,对所有内存分配进行限制

外部命令导致程序变慢 

        在java程序中操作shell脚本RunTime.getRuntime().exec()获取信息,这种外部调用在java虚拟机中十分耗费资源,即使外部命令本身可以很快的执行,但是频繁的创建进程的消耗也很客观。java虚拟机执行这条命令RunTime.getRuntime().exec(),首先复制一个和当前虚拟机拥有相同环境变量的进程,再用这个进程区执行外部命令,然后退出这个进程,系统。处理器的消耗都很大,内存负担也很重。

        解决方案

        去掉shell脚本的执行,改为Java api获取信息

同步调用执行长耗时导致虚拟机崩溃

        A服务调用B服务,B服务需要长时间才能返回响应,当大量请求来临时,A服务调用B服务的请求大量无法在短时间内执行完毕,长时间下导致AB两服务速度不对等,大量的web请求、线程和socker连接等待,超过虚拟机承受范围崩溃。

        解决方案

        采用异步生产者消费者模型

不恰当的数据结构导致内存过大 

        在HashMap<Long,Long> 结构中,只有Key和Value所存放的两个长整型数据是有效数据,共16B ( 2x8B ) 。这两个长整型数据包装成java.lang.Long对象之后,就分别具有8B的MarkWord、8B的Klass指针 ,在加8B存储数据的long值。在这两个Long对赢组成Map.Entry之后 ,又多了 16B的对象头,然后一个8B的next字段和4B的int型的hash字段 ,为了对齐,还必须添加4B的空白填充,最后还有HashMap中对这个Entry的8B的引用 ,这样增加两个长整型数字,实际耗费的内存为 (Long(24B)x2)+Entry(32B)+HashMap Ref(8B)=88B,空间效率为16B/88B=18%,实在太低了。

安全点导致长时间停顿

        安全点使以是否让程序长时间运行为特征,所以方法调用,循环跳转,异常跳转这些位置都可能被设置成安全点。hotsopt对安全点优化措施,认为循环较少执行时间不会太长。小于int被称为可数循环,不放置安全点,大于int则成为不可数循环,放置安全点。当线程A在耗时的可数循环中,其他线程已经达到安全点将会等待线程A进入安全点,导致程序长时间停顿。

        解决方案

        优化耗时代码,将索引数据类型由int改为long

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值