案例分析
高性能硬件上的程序部署策略
方案一: 使用通过64位JDK使用大内存
问题:
- 内存大, GC时间长, 必须把Full GC的频率控制的足够低, 才不会影响用户使用
- 64位JDK性能差于32位的, 相同的程序在64位中消耗的内存大
- 堆溢出无法产生快照分析(快照高达十几G)
…
方案二: 使用若干个32位虚拟机建立逻辑集群来利用硬件资源, 前端负载均衡, 以方向代理的方式来分配用户请求
问题:
- 需要避免节点竞争全局的资源, 例如同时读写磁盘文件导致IO异常
- 很难高效率的利用某些连接池
- 依然受到32位内存限制
- 各节点的本地缓存造成浪费, 需要改成集中式缓存
集群间同步导致的内存溢出
略
堆外内存导致的溢出错误
除了java堆和永久代之外, 下面这些区域还会占用较多的内存, 这里内存的总和会受到操作系统进程最大内存的限制:
- Direct Memory: 可通过-XX: MaxDirectMemorySize调整大小, 内存不足时抛出OOM或OOM: Direct buffer memory
- 线程堆栈: 可通过-Xss调整大小, 内存不足时抛出SOF(纵向无法分配, 无法建立新的栈帧)或OOM(横向无法分配, 无法建立新的线程)
- Socket缓存区: 每个Socket连接都有Receive和Send两个缓存区, 分别占37kb和25kb的内存. 如果无法分配会抛出IOException: Too many open files
- JNI代码
- 虚拟机和GC
外部命令导致系统缓慢
比如在java代码中调用shell脚本
服务器JVM进程崩溃
略