精华内容
下载资源
问答
  • 2021-02-26 18:56:33

    online的环境中发现有一个java进程内存占用一直增大,xmx设置的6144m 但是用top -p 查询占用了8.9G内存,上次用jmap查看堆内存只有3个多G 应该继续排查一下堆外内存可能存在的内存泄漏问题。

    [root@localhost logs]# top -p 755

    top - 09:56:24 up 5 days, 1:56, 2 users, load average: 1.27, 3.27, 5.02

    Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie

    %Cpu(s): 2.6 us, 0.5 sy, 0.0 ni, 96.0 id, 0.8 wa, 0.0 hi, 0.1 si, 0.0 st

    KiB Mem : 32661788 total, 259524 free, 30131472 used, 2270792 buff/cache

    KiB Swap: 31248380 total, 19591088 free, 11657292 used. 2014948 avail Mem

    PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND

    755 root 20 0 17.9g 8.9g 6808 S 1.3 28.4 441:16.82 java

    MALLOC_ARENA_MAX=4

    export JAVA_HOME JRE_HOME MYCAT_HOME PATH CLASSPATH MALLOC_ARENA_MAX

    GZIPInputStream 流未关闭引起的内存泄漏问题

    # 总核数 = 物理CPU个数 X 每颗物理CPU的核数

    # 总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数

    # 查看物理CPU个数

    cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l

    或grep 'physical id' /proc/cpuinfo | sort -u | wc -l

    # 查看每个物理CPU中core的个数(即核数)

    cat /proc/cpuinfo| grep "cpu cores"| uniq

    或者grep 'core id' /proc/cpuinfo | sort -u | wc -l

    # 查看逻辑CPU的个数

    cat /proc/cpuinfo| grep "processor"| wc -l

    或者grep 'processor' /proc/cpuinfo | sort -u | wc -l

    # 查看CPU信息(型号)

    cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c

    或者dmidecode -s processor-version

    #查看内 存信息

    cat /proc/meminfo

    更多相关内容
  • Java堆外内存泄露场景总结,包含几个常用的可能,如:JNI,NIO,AWT/Swing,Inflater&Deflater;
  • Java堆外内存泄露分析

    千次阅读 2019-02-28 16:12:10
    说明:...而top出来显示java占用内存是几个G,那么可能想到了是堆外内存泄漏。 需要安装google-perftools工具进行分析 1.先安装g++ 不然编译会报错:g++: comma...

    说明:https://blog.csdn.net/unix21/article/details/79161250  本文登录在本人另一个博客,这个博客相对比较精练

    查看堆内存占用正常,jvm垃圾回收也没有异常。而top出来显示java占用内存是几个G,那么可能想到了是堆外内存泄漏。

    需要安装google-perftools工具进行分析

    1.先安装g++

    不然编译会报错:g++: command not found

    # yum -y install gcc gcc-c++
    ----

    2.安装libunwind

    不建议版本>0.99据说有问题,这个需要FQ
    # wgethttp://download.savannah.gnu.org/releases/libunwind/libunwind-0.99.tar.gz
    # tar -xzvf libunwind-0.99.tar.gz
    # cd libunwind-0.99
    # ./configure  --prefix=/data0/java/deploy/google-perftools/local/libunwind
    # make && make install
    ---------

    3.安装gperftools

    # wget https://github.com/gperftools/gperftools/releases/download/gperftools-2.5/gperftools-2.5.tar.gz
    # tar -xzvf gperftools-2.5.tar.gz
    # cd gperftools-2.5
    # ./configure --prefix=/data0/java/deploy/google-perftools/local/gperftools-2.5/
    # make && make install
    -----------

    4.使配置生效
    # vim /etc/ld.so.conf.d/usr_local_lib.conf

    新增以下内容按i
    /data0/java/deploy/google-perftools/local/libunwind/lib
    按esc再:wq! #保存退出
    # /sbin/ldconfig  #执行此命令,使libunwind生效。 需要sudo权限
    -------------------
    5.加入环境变量
    # export LD_PRELOAD=/data0/java/deploy/google-perftools/local/gperftools-2.5/lib/libtcmalloc.so
    # export HEAPPROFILE=/data0/java/deploy/google-perftools/local/tmp/gzip
    ------
    6.运行java程序

    # java -classpath /xxx.jar com.xxx.xxx.HttpMain

    就会在/data0/java/deploy/google-perftools/local/目录下生成heap文件

    如果是持续运行的程序需要ctrl+c会生成dump文件。

    7.分析函数调用
    # /data0/java/deploy/google-perftools/local/gperftools-2.5/bin/pprof --text /usr/lib/jdk/jdk1.8.0_161/bin/java /data0/java/deploy/google-perftools/local/tmp/gzip.0001.heap

    下面就是分析的函数:

    也可以直接导出完整的函数到文本

    # /data0/java/deploy/google-perftools/local/gperftools-2.5/bin/pprof --text /usr/lib/jdk/jdk1.8.0_161/bin/java /data0/java/deploy/google-perftools/local/tmp/gzip.0001.heap > gzip.0001.heap.log

    下面选取一部分:

     

    Total: 21.6 MB
        17.9  82.5%  82.5%     17.9  82.5% os::malloc@9240a0
         3.0  13.9%  96.4%      3.0  13.9% init
         0.5   2.4%  98.8%      0.5   2.4% readCEN
         0.2   0.9%  99.7%      0.2   0.9% updatewindow
         0.0   0.2%  99.8%      0.0   0.2% inflateInit2_
         0.0   0.1%  99.9%      0.0   0.1% _dl_new_object
         0.0   0.0%  99.9%      0.0   0.0% _dl_allocate_tls
         0.0   0.0%  99.9%      0.0   0.0% _nl_intern_locale_data
         0.0   0.0% 100.0%      0.0   0.0% _dl_check_map_versions
         0.0   0.0% 100.0%      0.0   0.0% strdup
         0.0   0.0% 100.0%      0.5   2.4% ZIP_Put_In_Cache0
         0.0   0.0% 100.0%      0.0   0.0% _dl_map_object_deps
         0.0   0.0% 100.0%      0.0   0.0% nss_parse_service_list
         0.0   0.0% 100.0%      0.0   0.0% getpwuid
         0.0   0.0% 100.0%      0.0   0.0% newEntry
         0.0   0.0% 100.0%      0.0   0.2% Java_java_util_zip_Inflater_init
         0.0   0.0% 100.0%      0.0   0.0% __nss_database_lookup
         0.0   0.0% 100.0%      0.0   0.0% expand_dynamic_string_token
         0.0   0.0% 100.0%      0.0   0.0% initLoopbackRoutes
         0.0   0.0% 100.0%      0.0   0.0% JLI_MemAlloc
         0.0   0.0% 100.0%      0.0   0.0% __tzfile_read
         0.0   0.0% 100.0%      0.0   0.1% dl_open_worker
         0.0   0.0% 100.0%      0.0   0.0% add_to_global
         0.0   0.0% 100.0%      0.0   0.0% add_name_to_object
         0.0   0.0% 100.0%      0.0   0.0% tsearch
         0.0   0.0% 100.0%      0.0   0.0% _nl_load_locale_from_archive
         0.0   0.0% 100.0%      0.0   0.0% __nss_lookup_function
         0.0   0.0% 100.0%      0.0   0.0% __tzstring
         0.0   0.0% 100.0%      0.0   0.1% _dlerror_run
         0.0   0.0% 100.0%      0.0   0.0% std::basic_string::_Rep::_S_create
         0.0   0.0% 100.0%      0.0   0.0% ParseLocale
         0.0   0.0% 100.0%      0.0   0.0% new_composite_name
         0.0   0.0% 100.0%      0.0   0.0% __static_initialization_and_destruction_0 (inline)

     

     

    参考此文:

     

     

    google-perftools安装

    使用堆外内存  (说明什么是堆外内存以及怎么用堆外内存和问题)

    java堆外内存泄漏

    perftools查看堆外内存并解决hbase内存溢出

    ===============

    下面这个是个人博客 怕没过几天网站不存在了,所以备份下

    原文地址:http://www.dylan326.com/2017/09/28/gperftools/

     

    perftools wiki地址 :https://github.com/gperftools/gperftools/wiki
    安装perftools

    工具主要作用分析程序:heap、cpu等,常用于c/c++程序分析
    使用文档如下:
    https://gperftools.github.io/gperftools/heapprofile.html
    https://gperftools.github.io/gperftools/heap_checker.html
    https://gperftools.github.io/gperftools/cpuprofile.html

    JVM堆外内存分析

    本文针对于 Oracle Hotspot jvm 虚拟机
    JVM 进程占用大小一般约等于: heap + perm + thread stack + nio directbuffer
    当然还有其他占用,一般情况来看native memory跟踪可以使用NMT参数 -XX:NativeMemoryTracking
    详情wiki : https://docs.oracle.com/javase/8/docs/technotes/guides/vm/nmt-8.html
    JVM常见内存泄漏检查方式可以按照 oracle提供的文档: http://www.oracle.com/technetwork/java/javase/memleaks-137499.html
    其中dbx是和perftools类似工具。

    除此之外
    进程内存在用在linux 面下top,pmap 等工具是较好确定进程内存的手段, 在/proc/${pid}/ 目录下smaps文件等查看RSS,虚拟内存,swap占用等。
    pmap 找到内存申请的地址块, 可以使用gdb attach 后 dump 某一段的内存地址 ,后查看内存的数据。 注意gdb attach 进程会暂停, 线上谨慎操作。

    如果发现进程内存过高,可能需要注意下程序是否存在堆外内存泄漏问题,java进程出现的堆外内存泄漏常见有如下几个方面:

    • JNI
    • NIO directbuffer 泄漏
    • gzip (本文案例就是此类)

    网络编程中程序中,nio directbuffer 有监控工具可以查看, directbuffer使用量、并且可以设置最大直接内存buffer。

    JVM 进程使用perftools 做分析

    案例中发现的问题jetty 服务在某版本的JDK(jdk7u80~jdk8u045等 应该7u80后的版本在本文章编写时候都有)出现的内存泄漏问题分析和查找

    1、安装perftools 注意配置安装目录, 找到对应的文件路径
    2、启动java程序时候携带环境变量(可以参照 perftools wiki帮助 写的较为明确, 文档主要针对正对c/c++程序, Hotspot主要是c++写的)
    export LD_PRELOAD=/opt/perftools/lib/libtcmalloc.so # 安装后的库文件路径
    export HEAPPROFILE=/opt/mybin.hprof #heap分析文件路径和文件
    特别注意目录和文件权限是否是进程用户可使用的
    3、运行后启动程序后
    4、pprof执行程序(注意路径),分析这些heap文件 pprof –help查看使用方式
    ./perftools/bin/pprof –text *.heap 以文本结果展示heap的分析文件, 结果说明见perftools wiki文档

     

    Total: 55838.9 MB
    41320.8 74.0% 74.0% 41320.8 74.0% updatewindow
    9018.8 16.2% 90.2% 9018.8 16.2% inflateInit2_
    1559.4 2.8% 92.9% 1559.4 2.8% os::malloc@907260
    1556.4 2.8% 95.7% 1556.4 2.8% init
    587.5 1.1% 96.8% 587.5 1.1% 00007fb480508a66
    551.4 1.0% 97.8% 551.4 1.0% 00007f2b1d6f4a66
    451.5 0.8% 98.6% 451.5 0.8% 00007fb48177e8e9
    183.1 0.3% 98.9% 183.1 0.3% 00007fb46c1b6c91
    128.2 0.2% 99.1% 128.2 0.2% 00007fb480508245
    120.4 0.2% 99.4% 120.4 0.2% 00007f2b1d6f4245
    111.0 0.2% 99.6% 9129.7 16.4% Java_java_util_zip_Inflater_init
    102.8 0.2% 99.7% 102.8 0.2% 00007f2b1e96a8e9
    74.2 0.1% 99.9% 74.2 0.1% readCEN
    45.8 0.1% 100.0% 45.8 0.1% 00007f2b09392c91
    7.5 0.0% 100.0% 7.5 0.0% 00007fb4805025b6
    4.5 0.0% 100.0% 4.5 0.0% 00007fb48192162d

     

     

     

    .对于上述问题表现的jdk1.7.0_76不会出现

     

     

    jdk1.7.0_80,jdk1.8.0_45以上明显出现。
    用过pmap分析过 主要都是64m内存块较多, 查看过数据都是jar load相关的数据当时没引起注意
    分析主要在updatewindow,Java_java_util_zip_Inflater_init , 这个是gzip相关, 于是搜索相关资料
    结论如下:
    ‘’’Note that the URLClassLoader was properly disposed of, with a call to close() first, and that the ServiceLoader’s reload() method was also called to flush it’s internal cache.
    This is NOT specific to the ServletContainerInitializer, it happens with any class that is loaded via the ServiceLoader.
    File handles remain to the *.jar until the app’s process is stopped.’’’

    网上查找相关资料
    jdk 问题 http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8156014
    jetty issue https://github.com/eclipse/jetty.project/issues/231

    处理方法,以下其一

    关于堆外内存:《堆外内存 之 DirectByteBuffer 详解

    DirectByteBuffer是Java用于实现堆外内存的一个重要类,我们可以通过该类实现堆外内存的创建、使用和销毁。

    DirectByteBuffer该类本身还是位于Java内存模型的堆中。堆内内存是JVM可以直接管控、操纵。
    而DirectByteBuffer中的unsafe.allocateMemory(size);是个一个native方法,这个方法分配的是堆外内存,通过C的malloc来进行分配的。分配的内存是系统本地的内存,并不在Java的内存中,也不属于JVM管控范围,所以在DirectByteBuffer一定会存在某种方式来操纵堆外内存。
    在DirectByteBuffer的父类Buffer中有个address属性:

    public abstract class Buffer {
    
        /**
         * The characteristics of Spliterators that traverse and split elements
         * maintained in Buffers.
         */
        static final int SPLITERATOR_CHARACTERISTICS =
            Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED;
    
        // Invariants: mark <= position <= limit <= capacity
        private int mark = -1;
        private int position = 0;
        private int limit;
        private int capacity;
    
        // Used only by direct buffers
        // NOTE: hoisted here for speed in JNI GetDirectBufferAddress
        long address;

    address只会被直接缓存给使用到。之所以将address属性升级放在Buffer中,是为了在JNI调用GetDirectBufferAddress时提升它调用的速率。address表示分配的堆外内存的地址。

    ======================

    堆外内存常配合使用System GC

    这里说的堆外内存主要针对java.nio.DirectByteBuffer,这些对象的创建过程会通过Unsafe接口直接通过os::malloc来分配内存,然后将内存的起始地址和大小存到java.nio.DirectByteBuffer对象里,这样就可以直接操作这些内存。这些内存只有在DirectByteBuffer回收掉之后才有机会被回收,因此如果这些对象大部分都移到了old,但是一直没有触发CMS GC或者Full GC,那么悲剧将会发生,因为你的物理内存被他们耗尽了,因此为了避免这种悲剧的发生,通过-XX:MaxDirectMemorySize来指定最大的堆外内存大小,当使用达到了阈值的时候将调用System.gc来做一次full gc,以此来回收掉没有被使用的堆外内存,具体堆外内存是如何回收的,其原理机制又是怎样的,还是后面写篇详细的文章吧

    JVM源码分析之SystemGC完全解读

    展开全文
  • JAVA系统堆外内存泄露

    2021-03-14 20:53:51
    JAVA系统堆内存泄露问题描述最近有个系统在做压力测试,环境配置:CentOS系统 4核CPU 8g内存 jdk1.6.0_25,jvm配置-server -Xms...排查过程top命令查看内存占用如下然后查看java堆内存分布情况image.png查看堆内...

    JAVA系统堆外内存泄露

    问题描述

    最近有个系统在做压力测试,

    环境配置:

    CentOS系统 4核CPU 8g内存 jdk1.6.0_25,jvm配置-server -Xms2048m -Xmx2048m

    出现问题如下

    执行并发300人,压测持续1个小时内存使用率从20%上升到100%,tps从1100多降低到600多。

    排查过程

    top命令查看内存占用如下

    然后查看java堆内存分布情况

    0c51d8fa3ce8

    image.png

    查看堆内存占用正常,jvm垃圾回收也没有异常。

    0c51d8fa3ce8

    image.png

    然后想到了是堆外内存泄漏,由于系统中用的jsf接口比较多,底层都是依赖的netty。首先考虑的是java中nio包下的DirectByteBuffer,可以直接分配堆外内存,不过该类分配的内存也有大小限制的,可以直接通过-XX:MaxDirectMemorySize=1g 进行指定,并且内存不够用的时候代码中会显式的调用System.gc()方法来触发FullGC,如果内存还是不够用就会抛出内存溢出的异常。为了验证这一想法,于是在启动参数中通过-XX:MaxDirectMemorySize=1g指定了堆外内存大小为1g,然后再次进行压测,发现内存还是在持续增长,然后超过了堆内存2g和堆外内存1g的总和,并且也没有发现有内存溢出的异常,也没有频繁的进行FullGC。所以可能不是nio的DirectByteBuffer占用的堆外内存。

    为了分析堆外内存到底是谁占用了,不得不安装google-perftools工具进行分析,安装步骤如下:

    它的原理是在java应用程序运行时,当调用malloc时换用它的libtcmalloc.so,这样就能做一些统计了

    下载http://download.savannah.gnu.org/releases/libunwind/libunwind-0.99-beta.tar.gz,

    ./configure

    make

    sudo make install //需要root权限

    下载http://google-perftools.googlecode.com/files/google-perftools-1.8.1.tar.gz,

    ./configure --prefix=/home/admin/tools/perftools --enable-frame-pointers

    make

    sudo make install //需要root权限

    修改

    lc_config:

    sudo vi /etc/ld.so.conf.d/usr-local_lib.conf,加入/usr/local/lib(libunwind的lib所在目录)

    执行

    sudo /sbin/ldconfig,使libunwind生效

    在应用程序启动前加入:

    export LD_PRELOAD=/home/admin/tools/perftools/lib/libtcmalloc.so

    export HEAPPROFILE=/home/admin/heap/gzip

    启动应用程序,此时会在/home/admin/heap下看到诸如gzip_pid.xxxx.heap的heap文件,

    可使用/home/admin/tools/perftools/bin/pprof --text

    math?formula=JAVA_HOME%2Fbin%2Fjava%20test_pid.xxxx.heap%E6%9D%A5%E6%9F%A5%E7%9C%8B%20%2Fhome%2Fadmin%2Ftools%2Fperftools%2Fbin%2Fpprof%20--textJAVA_HOME/bin/java gzip_22366.0005.heap > gzip-0005.txt

    然后查看分析结果如下

    Total: 4504.5 MB

    4413.9 98.0% 98.0% 4413.9 98.0% zcalloc

    60.0 1.3% 99.3% 60.0 1.3% os::malloc

    16.4 0.4% 99.7% 16.4 0.4% ObjectSynchronizer::omAlloc

    8.7 0.2% 99.9% 4422.7 98.2% Java_java_util_zip_Inflater_init

    4.7 0.1% 100.0% 4.7 0.1% init

    0.3 0.0% 100.0% 0.3 0.0% readCEN

    0.2 0.0% 100.0% 0.2 0.0% instanceKlass::add_dependent_nmethod

    0.1 0.0% 100.0% 0.1 0.0% _dl_allocate_tls

    0.0 0.0% 100.0% 0.0 0.0% pthread_cond_wait@GLIBC_2.2.5

    0.0 0.0% 100.0% 1.7 0.0% Thread::Thread

    0.0 0.0% 100.0% 0.0 0.0% _dl_new_object

    0.0 0.0% 100.0% 0.0 0.0% pthread_cond_timedwait@GLIBC_2.2.5

    0.0 0.0% 100.0% 0.0 0.0% _dlerror_run

    0.0 0.0% 100.0% 0.0 0.0% allocZip

    0.0 0.0% 100.0% 0.0 0.0% __strdup

    0.0 0.0% 100.0% 0.0 0.0% _nl_intern_locale_data

    0.0 0.0% 100.0% 0.0 0.0% addMetaName

    可以看到是Java_java_util_zip_Inflater_init这个函数一直在进行内存分配,查看java源码原来是

    public GZIPInputStream(InputStream in, int size) throws IOException {

    super(in, new Inflater(true), size);

    usesDefaultInflater = true;

    readHeader(in);

    }

    原来java中gzip解压缩类耗尽了系统内存,然后跟踪源码到了系统里边使用的jimdb客户端SerializationUtils类,jimdb客户端使用该工具类对保存在jimdb中的key和对象进行序列化和反序列化操作,并且在对Object类型的进行序列化和反序列化的时候用到了gzip解压缩,

    也就是在调用jimdb客户端的getObject和setObject方法时,内部会使用java的GZIPInputStream和GZIPOutputStream解压缩功能,当大并发进行压测的时候,就会造成内存泄漏,出现内存持续增长的问题,当压测停止后,内存也不会释放。

    暂时的解决方案

    1、升级jdk版本为jdk7u71 ,压测一段时间后,发现内存增长有所减慢,并且会稳定在一定的范围内,不会把服务器的所有内存耗尽。猜测可能是jdk1.6版本的bug

    2、尽量不要使用jimdb客户端的getObject和setObject方法,如果真的需要保存对象,可以自己实现序列化和反序列化,不要解压缩功能,因为对象本来就不大,压缩不了多少空间。

    如真的需要解压缩功能,最好设置解压缩阀值,当对象大小超过阀值之后在进行解压缩处理,不要将所有对象都进行解压缩处理。

    展开全文
  • java堆外内存泄漏

    万次阅读 2016-07-14 13:53:01
    java堆外内存泄漏 最近有个系统在做压力测试, 环境配置: 4核CPU 8g内存 jdk1.6.0_25,jvm配置-server -Xms2048m -Xmx2048m 出现问题如下 执行并发300人,压测持续1个小时内存使用率从20%上升到100%,tps从1100多...

    问题描述

    最近有个系统在做压力测试,

    环境配置:

    4核CPU 8g内存 jdk1.6.0_25,jvm配置-server -Xms2048m -Xmx2048m 

    出现问题如下

    执行并发300人,压测持续1个小时内存使用率从20%上升到100%,tps从1100多降低到600多。

    排查过程

    top命令查看内存占用如下


    然后查看java堆内存分布情况

     

    查看堆内存占用正常,jvm垃圾回收也没有异常。

    然后想到了是堆外内存泄漏,由于系统中用的jsf接口比较多,底层都是依赖的netty。首先考虑的是java中nio包下的DirectByteBuffer,可以直接分配堆外内存,不过该类分配的内存也有大小限制的,可以直接通过-XX:MaxDirectMemorySize=1g 进行指定,并且内存不够用的时候代码中会显式的调用System.gc()方法来触发FullGC,如果内存还是不够用就会抛出内存溢出的异常。为了验证这一想法,于是在启动参数中通过-XX:MaxDirectMemorySize=1g指定了堆外内存大小为1g,然后再次进行压测,发现内存还是在持续增长,然后超过了堆内存2g和堆外内存1g的总和,并且也没有发现有内存溢出的异常,也没有频繁的进行FullGC。所以可能不是nio的DirectByteBuffer占用的堆外内存。

    为了分析堆外内存到底是谁占用了,不得不安装google-perftools工具进行分析,安装步骤如下:

    它的原理是在java应用程序运行时,当调用malloc时换用它的libtcmalloc.so,这样就能做一些统计了 
    下载http://download.savannah.gnu.org/releases/libunwind/libunwind-0.99-beta.tar.gz,
    ./configure
    make
    sudo make install //需要root权限
    下载http://google-perftools.googlecode.com/files/google-perftools-1.8.1.tar.gz, 
    ./configure --prefix=/home/admin/tools/perftools --enable-frame-pointers
    make
    sudo make install //需要root权限
    修改
    lc_config:
    sudo vi /etc/ld.so.conf.d/usr-local_lib.conf,加入/usr/local/lib(libunwind的lib所在目录)
    执行
    sudo /sbin/ldconfig,使libunwind生效
    在应用程序启动前加入:
    export LD_PRELOAD=/home/admin/tools/perftools/lib/libtcmalloc.so
    export HEAPPROFILE=/home/admin/heap/gzip
    启动应用程序,此时会在/home/admin/heap下看到诸如gzip_pid.xxxx.heap的heap文件,
    可使用/home/admin/tools/perftools/bin/pprof --text $JAVA_HOME/bin/java test_pid.xxxx.heap来查看
    /home/admin/tools/perftools/bin/pprof --text $JAVA_HOME/bin/java gzip_22366.0005.heap > gzip-0005.txt

    然后查看分析结果如下

    Total: 4504.5 MB
    4413.9 98.0% 98.0% 4413.9 98.0% zcalloc
    60.0 1.3% 99.3% 60.0 1.3% os::malloc
    16.4 0.4% 99.7% 16.4 0.4% ObjectSynchronizer::omAlloc
    8.7 0.2% 99.9% 4422.7 98.2% Java_java_util_zip_Inflater_init
    4.7 0.1% 100.0% 4.7 0.1% init
    0.3 0.0% 100.0% 0.3 0.0% readCEN
    0.2 0.0% 100.0% 0.2 0.0% instanceKlass::add_dependent_nmethod
    0.1 0.0% 100.0% 0.1 0.0% _dl_allocate_tls
    0.0 0.0% 100.0% 0.0 0.0% pthread_cond_wait@GLIBC_2.2.5
    0.0 0.0% 100.0% 1.7 0.0% Thread::Thread
    0.0 0.0% 100.0% 0.0 0.0% _dl_new_object
    0.0 0.0% 100.0% 0.0 0.0% pthread_cond_timedwait@GLIBC_2.2.5
    0.0 0.0% 100.0% 0.0 0.0% _dlerror_run
    0.0 0.0% 100.0% 0.0 0.0% allocZip
    0.0 0.0% 100.0% 0.0 0.0% __strdup
    0.0 0.0% 100.0% 0.0 0.0% _nl_intern_locale_data
    0.0 0.0% 100.0% 0.0 0.0% addMetaName

    可以看到是Java_java_util_zip_Inflater_init这个函数一直在进行内存分配,查看java源码原来是

    public GZIPInputStream(InputStream in, int size) throws IOException {
    super(in, new Inflater(true), size);
     usesDefaultInflater = true;
     readHeader(in);
    }


    原来java中gzip解压缩类耗尽了系统内存,然后跟踪源码到了系统里边使用的SerializationUtils类,jimdb客户端使用该工具类对保存在缓存中的key和对象进行序列化和反序列化操作,并且在对Object进行序列化和反序列化的时候用到了java的GZIPInputStream和GZIPOutputStream解压缩功能,当大并发进行压测的时候,就会造成内存泄漏,出现内存持续增长的问题,当压测停止后,内存也不会释放。

    暂时的解决方案

    1、升级jdk版本为jdk7u71 ,压测一段时间后,发现内存增长有所减慢,并且会稳定在一定的范围内,不会把服务器的所有内存耗尽。猜测可能是jdk1.6版本的bug

    2、尽量不要GZIPInputStream和GZIPOutputStream解压缩功能,因为如果对象本来就不大,压缩不了多少空间。

    如真的需要解压缩功能,最好设置解压缩阀值,当对象大小超过阀值之后在进行解压缩处理,不要将所有对象都进行解压缩处理。

    展开全文
  • JVM 堆外内存泄漏

    2021-03-10 09:37:05
    首先开启:-XX:NativeMemoryTracking=detail然后jcmd pid VM.native_...此处需要关注两个点:第一,Total行的committed数值是否等于进程占用的物理内存,如果不等,说明有C++等native code分配的内存,可参考Java...
  • 1. JVM 感知容器资源Java 应用部署在 Kubernetes 集群里,每个容器只运行一个进程, JVM 的启动命令是...为了避免因为修改大小而重新打包,从 JDK 8u191 版本开始支持 JVM 感知容器资源限制,这样在调整 JVM 内存...
  • JVM-堆外内存泄漏

    2021-07-14 22:02:30
    java 8下是指除了Xmx设置的java堆(java 8以下版本还包括MaxPermSize设定的持久代大小),java进程使用的其他内存。主要包括:DirectByteBuffer分配的内存,JNI里分配的内存,线程栈分配占用的系统内存,jvm本身...
  • 先上一个代码demo,利用unsafe开辟1g内存空间,不释放。 import java.lang.reflect.Field; import java.util.concurrent.CountDownLatch; import sun.misc.Unsafe; public class OutOfHeapOOM { public static ...
  • 安装gperftools(googleperformancetools)来分析java堆外(超出-Xmx所设置的heap size的部分)内存泄露如果是泄漏,则最大内存使用不会超过-Xmx所设置的大小,基本上使用jmap之类的都直接可以查到问题。...
  • 堆外内存泄漏排查 直接内存:指的是Java应用程序通过直接方式从操作系统中申请的内存,也叫堆外内存,因为这些对象分配在Java虚拟机的(严格来说,应该是JVM的内存,但是是这块内存中最大的)以外。 直接内存...
  • 本文涉及以下内容开启NMT查看JVM内存使用情况通过pmap命令查看进程物理内存使用情况smaps查看进程内存地址gdb命令dump内存块背景最近收到运维反馈,说有项目的一个节点的RSS已经是Xmx的两倍多了,因为是ECS机器所以...
  • 主要介绍了Java 分析并解决内存泄漏的实例,帮助大家更好的理解和学习Java,感兴趣的朋友可以了解下
  • 一、堆外内存组成通常JVM的参数我们会配置-Xms 初始内存-Xmx 最大内存-XX:+UseG1GC/CMS 垃圾回收器-XX:+DisableExplicitGC 禁止显示GC-XX:MaxDirectMemorySize 设置最大堆外内存,默认是-xmx-survivor,也就是...
  • 记录一次线上JVM堆外内存泄漏问题的排查过程与思路,其中夹带一些JVM内存分配机制以及常用的JVM问题排查指令和工具分享,希望对大家有所帮助。 在整个排查过程中,我也走了不少弯路,但是在文章中我仍然会把完整的...
  • 一、JVM内存的分配及垃圾回收  对于JVM的内存规则,应该是老生常谈的东西了,这里我就简单的说下: ...但是如果不了解其中的原委,很容易内存泄漏,只能两眼望天了!  垃圾回收,大致可以分为下
  • 堆外内存泄漏”排查及经验总结

    千次阅读 2019-07-09 15:56:35
    背景 为了更好地实现对项目...笔者被叫去帮忙查看原因,发现配置了4G内存,但是实际使用的物理内存竟然高达7G,确实不正常。JVM参数配置是“-XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -XX:+AlwaysPre...
  • 最近发现服务器内存使用持续增长且增长速率大,怀疑是内存泄露导致的。 最终定位到是因为程序中存在线程池频繁创建但未销毁问题导致线程泄露,进而影响内存使用增长。 Tips:本文不记录排错过程,只记录可疑点及...
  • Java堆外内存:堆外内存回收方法

    千次阅读 2019-10-24 17:36:17
    一、JVM内存的分配及垃圾回收  对于JVM的内存规则,应该是老生常谈的东西了,这里我就简单的说下:  新生代:一般来说新创建的对象都分配在这里。  年老代:经过几次垃圾回收,新生代的对象就会放在年老代里面...
  • Java应用堆外内存泄漏排查

    千次阅读 2020-01-25 22:18:13
    背景 我司商城系统生产服务隔一段时间就挂掉一次,所有的机器都有这个问题,而且问题出现的...2、根据pid查询java应用堆内存使用情况,以及应用进程占用系统内存情况 #查看java程序GC情况以及堆内内存使用情况 ...
  • 底层通讯使用netty4.1版本,然而在使用的时候出现了oom异常,这里记录一次堆外内存泄露排查过程,方便后续定位。一:知识点堆外内存,就是非内存空间,java可以通过Unsafe类的native方法进行操作,由于不受制于...
  • 在一个风和日丽,艳阳高照的夜晚。像往常一样准备上线, 拉镜像,停服务,启动最版本的镜像。...卧槽 事情大发了,赶紧给docker镜像设置内存,让它内存到了自动爆掉重启,不至于影响机器上其他服务。先这样将就一下(其
  • 开发过程中,我们遇到了堆外内存泄漏的问题——服务会出现假死现象(看似服务进程还跑着,但是没有业务响应)。 查看logback的error日志中记录下下面的信息: [location-center:192.168.5.14:8017] [,] 2021-07-27 ...
  • Java堆外内存使用

    千次阅读 2018-10-24 21:49:21
    JVM内部会把所有内存分成Java使用的堆内存和Native使用的内存,它们之间是不能共享的,就是说当你的Native内存用完了时,如果Java堆又有空闲内存,这时Native会重新向Jvm申请,而不是直接使用Java堆内存。...
  • java堆外内存排查方式

    2021-04-22 20:05:50
    堆外内存泄漏”排查及经验总结 https://zhuanlan.zhihu.com/p/60976273
  • 上一讲我介绍了 JVM 内存区域的划分,总结了相关的一些概念,今天我将结合 JVM 参数、工具等方面,进一步分析 JVM 内存结构,包括外部资料相对较少的堆外部分。今天我要问你的问题是,如何监控和诊断 JVM 内和堆外...
  • Java netty获取堆外内存占用

    千次阅读 2020-10-20 09:57:05
    在使用了netty的系统中,有时会出现内存泄露的问题,我们就需要去监控这个堆外内存的占用,以排查是否是堆外泄露,下面的代码就是查看堆外内存的。可以写个定时任务,持续调用doReport方法来获取堆外内存。 netty...
  • 文章目录配置说明排查之路视频教程图文教程数据表格相关链接后记 配置说明 ...原因:sun 的老旧框架,Clip.close(),音频数据 audioData[] 无法释放,从而导致堆内存泄露 工具:JConsole...
  • 堆外内存泄漏排查

    万次阅读 2020-08-21 14:42:39
    堆外内存泄漏排查 直接内存:指的是Java应用程序通过直接方式从操作系统中申请的内存,也叫堆外内存,因为这些对象分配在Java虚拟机的(严格来说,应该是JVM的内存,但是是这块内存中最大的)以外。 直接内存...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 83,745
精华内容 33,498
关键字:

java堆外内存泄漏

java 订阅