堆外内存导致溢出错误
例如一个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