1.假如一个新的服务性能能足够高,足够强大,但是使用后发现使用效果不理想,经常出现长时间的停顿

这可能是因为64位JDK不限制堆空间的大小,在使用吞吐量优先的收集器的时候,Full GC可能会高达14秒,并且由于程序设计的关系,要将文档从磁盘中提取出来,导致

出现了很多的大对象,而且大对象没有及时的清理,导致很快填满了内存,以至于Full GC

而且,这也和堆空间的极大有关系,在这种12gb的超大堆空间中,必须避免Full GC的出现,或者说减少Full的出现,避免出现长达十几秒的停顿

同时,如果使用了超大堆空间,还会存在一下的问题

1.内存回收导致的长时间停顿

2.可能由于超大的堆空间,导致在OutOfMemoryError的时候无法保存dump文件

3.由于自动地址对齐导致的消耗内存过高

2.在某些情况下,虚拟机经常抛出内存溢出异常,但是

加入了-XX +HeapDumpOnOutOfMemoryError,也不会进行堆转储文件的产生,在监视软件中也没有出现其他问题

最后发现问题在于非JVM内存溢出导致的错误

也就是非堆内存Direct Memory导致的,

Direct Memory现在并不像新生代,老年代一样,发现空间不足就通知收集器进行gc

只能是垃圾收集器在Full GC后,顺手进行清理掉内存中的废弃对象,不然就只能等到内存溢出异常,在catch中进行system.gc了

如果还不行就抛出内存溢出异常了

常见的其他内存区域还有

Direct Memory:可以通过 -XX:MaxDirectMemorySize 调整大小,内存不足进行抛出OutOfMemoryError

栈:通过-Xss进行调节,内存不足的时候抛出StackOverflowError或者OutOfMemoryError了

Socket缓冲区:每个Socket都连接着连个缓冲区,可能导致IOException异常

JNI代码

GC导致的内存消耗

3.调用导致的JVM崩溃

举一个例子:两个系统进行集成,通过异步的方式调用web服务,但是两个系统之间的处理速度不对等,会导致一方的积累了过多的web服务没有调用完成,或者完成返回,导致等待返回的线程越来越多,

最后服务器进程崩溃,解决方案, 还是采用消息队列比较好

4.不恰当的数据结构导致内存占用过大

假如有一个服务器,采用64位虚拟机,平常一切无问题,但是在每10分钟加载一个80MB的数据文件到内存中

导致产生了超过了100万个HashMap 的集合,导致了长时间的停顿时间,具体日志如下

图片

这种原因一目了然,就是在加载后产生了大量对象,在产生后无法立即回收,导致的多次Miror GC 乃至于 Major GC

但是其根本原因还是由于这种加载方式,加上HashMap这种存储结构效率低导致的

发表评论

邮箱地址不会被公开。 必填项已用*标注