JVM内存分析andJVM优化

1、认识JVM的内存

通常我们说的分析java内存,指的是分析java的堆内存(heap memory),稍微扩展点,还可能涉及到持久带内存(jre7以前)或者Metaspace(jre8以后)。一般的垃圾回收等参数优化,都是集中到堆内存。

除了对内存,jvm的运行还需要其他本地内存(native memory),包括栈内存(Thread),编译器内存,垃圾回收器内存,代码、类等静态数据内存,以及三方代码占用的内存等等。

由于分析技术和考察的内容不同,我们从两个不同的分析层面,将内存分析分为“堆内存分析”和“本地内存分析”。

内存占用是个比较复杂的概念,不能简单的理解为当前进程占用了多少内存。在系统空闲内存很多的时候,最大化利用内存可以提高性能。在一个受限容器里面,限制进程可用的最大内存是一个好主意。

内存分析至少包含如下几个方面的任务:

a.       如何规划和限制进程占用的最大内存。

b.       分析内存占用的原因,解决内存泄露问题。

c.       如何根据实际运行环境和应用场景,合理设置内存参数,最大化性能。

2、堆内存分析

对内存的分析的资料比较多,一般比较常用。比如使用jmap和jhat将内存dump出来并分析对象实例,或者结合MemoryAnalyser等工具分析。

JVM还提供了jstat, jvisualvm等工具查看内存增长的趋势、变化情况,以及各个块的区域。

3、本地内存分析

本地内存分析比较复杂,这里只简单的介绍如何查看本地内存的 使用。

通过jstat命令查看本地内存:

  • Java Heap : reserved和commited一般对应-Xms128m -Xmx128m两个参数。

Class : reserved由虚拟机管理,通过一定算法计算出来。 commited一般和-XX:MaxMetaspaceSize=32m大小相关,但是可能超过-XX:MaxMetaspaceSize=32m的值。JIT运行的时候,也会导致reserved和commited的增长。

  • Thread: 线程大小。和线程数量成正比。

  • Code:JIT运行时用的大小。 reserved和commited分别对应-XX:InitialCodeCacheSize=16m和-XX:ReservedCodeCacheSize=16m。

  • 其他: 主要是JVM相关的内容。 可以不用关心。

观察本地内存,需要在JVM启动参数里面增加如下参数: 

-XX:NativeMemoryTracking=summary

然后通过jcmd查看:

     jcmd 17755 VM.native_memory summary

下面是命令执行结果的示例: 

Native Memory Tracking:

Total: reserved=1592030KB, committed=307938KB

-                 Java Heap (reserved=131072KB, committed=131072KB)

                            (mmap: reserved=131072KB, committed=131072KB)

-                     Class (reserved=1075815KB, committed=29363KB)

                            (classes #4823)

                            (malloc=615KB #6672)

                            (mmap: reserved=1075200KB, committed=28748KB)

-                    Thread (reserved=67106KB, committed=67106KB)

                            (thread #66)

                            (stack: reserved=66820KB, committed=66820KB)

                            (malloc=209KB #341)

                            (arena=77KB #131)

-                      Code (reserved=251936KB, committed=14296KB)

                            (malloc=2336KB #3508)

                            (mmap: reserved=249600KB, committed=11960KB)

-                        GC (reserved=21624KB, committed=21624KB)

                            (malloc=21192KB #206)

                            (mmap: reserved=432KB, committed=432KB)

-                  Compiler (reserved=227KB, committed=227KB)

                            (malloc=96KB #273)

                            (arena=131KB #3)

-                  Internal (reserved=2166KB, committed=2166KB)

                            (malloc=2134KB #7251)

                            (mmap: reserved=32KB, committed=32KB)

-                    Symbol (reserved=6697KB, committed=6697KB)

                            (malloc=4963KB #46864)

                            (arena=1734KB #1)

-    Native Memory Tracking (reserved=1031KB, committed=1031KB)

                            (malloc=9KB #106)

                            (tracking overhead=1022KB)

-               Arena Chunk (reserved=195KB, committed=195KB)

                            (malloc=195KB)

-                   Unknown (reserved=34160KB, committed=34160KB)

                            (mmap: reserved=34160KB, committed=34160KB)

4、内存分析和建议

1. JAVA内存测试主要关注堆内存, jstat命令输出为主; JAVA的本地内存以jcmd命令的输出为主(jcmd的committed比RSS大,但表示了进程可能使用的内存上限)。其他内存关注的必要性不是很大。

2. 如果关注top命令的RES内存,建议设置如下参数然后在进行测试, 防止linux系统的内存管理机制和JVM的内存优化导致数据不准确(他们的目标都是最大化利用内存,而不是限制内存使用)

   -server -Djava.compiler=none -Xms128m -Xmx128m -XX:InitialCodeCacheSize=16m -XX:ReservedCodeCacheSize=16m -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=64m -Dsun.reflect.inflationThreshold=2147483647

根据这个参数设置, 一个进程占用的RES最大值为: 128m(堆) + 16m(JIT)+ 128m(线程) + 64m(Class元数据)+ 64m(其他,包括Compiler/Internal/Symbol/Unknown等JVM内存)  = 400m

对于实际运行参数的建议:

实际运行的参数应该尽可能利用内存,初始即分配合理的内存,允许一定的扩展,下面的参数比较可取:

-server -Xms256m -Xmx512m -XX:InitialCodeCacheSize=32m -XX:ReservedCodeCacheSize=64m -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=128m -Dsun.reflect.inflationThreshold=2147483647

分配较大的初始内存不意味着一定需要这么多的内存才能够运行,运行环境设置较大的内存是很有意义的,特别是64位的操作系统。-Dsun.reflect.inflationThreshold=2147483647可以选择不配置,但是如果大量使用反射,

 不配置可能非常多的内存,相反,配置的话会带来一定的计算性能开销,实测的结果是建议配置的。

  • 14
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猰貐的新时代

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值