调优案例分析三【堆外内存导致的溢出错误】

2021-07-13  本文已影响0人  云芈山人

案例出于《深入理解Java虚拟机》第二版

场景

一个学校的小型项目:基于B/S的电子考试系统,为了实现客户端能实时地从服务器接收考试数据,系统使用了逆向AJAX技术(也称Comet或者Server Side Push),选用CometD1.1.1作为服务端推送框架,服务器是Jetty7.1.4,硬件为一台普通PC机,Core i5 CPU,4GB 内存,运行32位Windows操作系统。

问题

分析

经验

从实践经验的角度出发,除Java堆和永久代之外,我们注意到下面这些区域还会占用较多的内存,这里所有的内存总和受到操作系统进程最大内存的限制。

  1. Direct Memory:可通过-XX:MaxDirectMemorySize调整大小,内存不足时抛出OutOfMemoryError或者OutOfMemoryError:Direct buffer memory。
  2. 线程堆栈:可通过-Xss调整大小,内存不足时抛出StackOverflowError(纵向无法分配,即无法分配新的栈帧)或者OutOfMemoryError:unable to create new native thread(横向无法分配,即无法建立新的线程)。
  3. Socket缓存区:每个Socket连接都Receive和Send两个缓存区,分别占大约37KB和25KB内存,连接多的话这块内存占用也比较可观。如果无法分配,则可能会抛出IOException:Too many open files异常。
  4. JNI代码:如果代码中使用JNI调用本地库,那本地库使用的内存也不在堆中。
  5. 虚拟机和GC:虚拟机、GC的代码执行也要消耗一定的内存。
上一篇下一篇

猜你喜欢

热点阅读