Why does my Java process consume more memory than Xmx?

https://plumbr.eu/blog/why-does-my-java-process-consume-more-memory-than-xmx

java进程内存消耗会大于我们在

1
-Xmx
中指定的值.
1
-Xmx
仅仅限制了应用程序使用的heap大小.java进的内存消耗主要包括下面的东东:

1
Max memory = [-Xmx] + [-XX:MaxPermSize] + number_of_threads * [-Xss]+Other

Other:

  • Garbage collection(GC自己需要消耗内存来记录数据)
  • JIT optimization(JIT优化需要记录代码执行行为,Code cache-JIT编译完成后存放机器码)
  • Off-heap allocations(NIO/DirectMemory之类的东东)
  • JNI code(程序使用第三方JNI代码占用的内存)
  • Metaspace(jdk8使用它取代了permgen)

Understanding the OutOfMemoryError

https://plumbr.eu/blog/understanding-java-lang-outofmemoryerror

  • java.lang.OutOfMemoryError: Java heap space

    heap空间不足.一般加大

    1
    -Xmx
    
    .如果还不足就有可能是内存泄漏了.

  • java.lang.OutOfMemoryError: PermGen space

    permgen空间不足,默认的jvm配置得比较小,需要通过

    1
    -XX:MaxPermSize
    
    加大.动态代码生成技术和容器redeploy资源泄漏也会导致permgen不足

  • java.lang.OutOfMemoryError: GC overhead limit exceeded

    jvm gc行为中超过98%以上的时间去释放小于2%的堆空间时会报这个错误

  • java.lang.OutOfMemoryError: unable to create new native thread

    java没创建一个线程,会占用

    1
    -Xss
    
    大小空间.这个异常有可能是系统内存不足导致.如果系统内存充足,往往是ulimit -u限制了一个用户创建最大线程数造成的.

  • java.lang.OutOfMemoryError: Requested array size exceeds VM limit

    申请的数组大小超过jvm定义的阀值.

  • java.lang.OutOfMemoryError: request bytes for . Out of swap space?
  • java.lang.OutOfMemoryError: (Native method)

20 Obstacles to Scalability

本文罗列了20个影响伸缩性的瓶颈

10 Obstacles to Scaling Performance

  1. Two-Phase Commit

    两阶段提交需要等待参与方确认,延时太大.所以我们基本上使用best-effort 1pc+业务上的重试.

  2. Insufficient Caching

    各个层次都需要引入缓存机制,现在我们对browser cache/page cache还做得比较少.

  3. Slow Disk I/O, RAID 5, Multitenant Storage

    数据库服务起I/O很关键.如果只做raid建议做raid10.当然加上fushion io之类的加速卡更好.

  4. Serial Processing

    服务并行处理我们也还思考得比较少.比如对远程服务进行合理并行处理(可以考虑下java8中的CompletableFuture).对于缓存数据的获取,可以考虑批量获取.

  5. Missing Feature Flags

    特性开关,说大点就是服务降级,我们需要却分不同服务的重要等级,适当时候关闭某些服务,保证核心业务正常运行.

  6. Single Copy of the Database
  7. Using Your Database for Queuing
  8. Using a Database for Full-Text Searching
  9. Object Relational Models(orm很好用,但是缺少能hold住他的人)
  10. Missing Instrumentation(需要监控/profile工具)

10 Obstacles to Scaling Beyond Optimization Speed

  1. Lack of a Code Repository and Version Control
  2. Single Points of Failure
  3. Lack of Browse-Only Mode(对于内容型的网站,此功能非常重要)
  4. Weak Communication
  5. Lack of Documentation
  6. Lack of Fire Drills(却分演练,特别是大的运维调整,此项非常必要)
  7. Insufficient Monitoring and Metrics
  8. Cowboy Operations
  9. Growing Technical Debt
  10. Insufficient Logging

Mcrouter:基于 Memcached协议的缓存层流量管理工具

http://www.infoq.com/cn/news/2014/09/mcrouter-memcached

https://code.facebook.com/posts/296442737213493/introducing-mcrouter-a-memcached-protocol-router-for-scaling-memcached-deployments/

memcache不支持服务端路由,facebook开发了

1
mcrouter
(能够处理每秒50亿次的请求).它和memcached之间通过文本协议通信.扮演者memcached服务器的客户端,应用的服务端.他的特性很多,基本上都是我们需要的.我们现在使用的是二进制协议,需要修改为文本协议.

dubbo应用使用的线程池为

1
com.alibaba.dubbo.common.threadpool.support.fixed.FixedThreadPool
,如果当queue设置为0时,会使用
1
SynchronousQueue
,这个东东导致了任务线程执行”不均衡”(满足了大家的心理预期,其实这种不均衡方式减少了上下文切换,但是
1
SynchronousQueue
没有大小,不能起到任务缓冲的作用).

请在dubbo:protocol上加上queues大小(参考tomcat默认配置).

1
    <dubbo:protocol name="dubbo" port="${dubbo.provider.port}" threads="200" queues="100"/>

测试:

修改前:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
grep DubboServerHandler dubbo-demo.log |awk  -F '-'  '{print $6}' |awk  -F ']'  '{print $1}' |sort -n |uniq -c
     1 150
  1 151
  1 152
  1 153
  1 154
  1 168
  1 169
  1 170
117 171
   	5386 172
714 173
   	2646 174
   	3738 175
   	3105 180
   	6332 194
   	2483 195
   	4940 196
   	1211 197
   	5661 198
   	5428 199
   	1393 200

修改后:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
grep DubboServerHandler dubbo-demo.log |awk  -F '-'  '{print $6}' |awk  -F ']'  '{print $1}' |sort -n |uniq -c
507 1
498 2
496 3
501 15
488 16
494 17
523 18
502 19
494 20
503 21
491 22
507 23
 		...
 507 133
495 134
498 135
494 136
507 137
508 151
490 152
494 195
496 196
496 197
506 198
493 199
489 200