精华内容
下载资源
问答
  • JAVA程序内存泄漏综述

    2016-07-21 20:54:46
    JAVA程序内存泄漏综述
  • 虽然jvm有垃圾回收机制,如果程序编写不注意某些特定规则,仍然会导致java程序内存泄漏,最终可能出现OutOfMemory异常。 1.Java内存泄漏的原因 java中的对象从使用上分为2种类型,被引用(referenced)的和不被...

    虽然jvm有垃圾回收机制,如果程序编写不注意某些特定规则,仍然会导致java程序内存泄漏,最终可能出现OutOfMemory异常。

    1.Java内存泄漏的原因

    java中的对象从使用上分为2种类型,被引用(referenced)的和不被引用(unreferenced)的。垃圾回收只会回收不被引用的对象。被引用的对象,即使已经不再使用了,也不会被回收。因此如果程序中有大量的被引用的无用对象时,就是出现内存泄漏。

    2.java堆内存(Heap)泄漏

    jvm堆内存的大小是通过 -Xms 和 -Xmx两个参数指定的。

    2.1 对象被静态成员引用

    当大对象被静态成员引用时,会造成内存泄漏。

    示例:

    private Random random = new Random();
    
    public static final ArrayList<Double> list = new ArrayList<Double>(1000000);
    
    for (int i = 0; i < 1000000; i++) { list.add(random.nextDouble()); }

    ArrayList是在堆上动态分配的对象,正常情况下使用完毕后,会被gc回收,但是在此示例中,由于被静态成员list引用,而静态成员是不会被回收的,所以会导致这个很大的ArrayList一直停留在堆内存中。

    因此需要特别注意静态成员的使用方式,避免静态成员引用大对象或集合类型的对象(如ArrayList等)。

    2.2 String的intern方法

    在大字符串上调用String.intern() 方法,intern()会将String放在jvm的内存池中(PermGen ),而jvm的内存池是不会被gc的。因此如果大字符串调用intern()方法后,会产生大量的无法gc的内存,导致内存泄漏。

    如果必须要使用大字符串的intern方法,应该通过-XX:MaxPermSize参数调整PermGen内存的大小。

    2.3 读取流后没有关闭

    开发中经常忘记关闭流,这样会导致内存泄漏。因为每个流在操作系统层面都对应了打开的文件句柄,流没有关闭,会导致操作系统的文件句柄一直处于打开状态,而jvm会消耗内存来跟踪操作系统打开的文件句柄。
    示例:

    BufferedReader br = new BufferedReader(new FileReader(path));
    return br.readLine();

    要解决这个问题,在java8之前的版本中可以在finally中加入关闭操作:

     BufferedReader br = new BufferedReader(new FileReader(path));
        try {
            return br.readLine();
        } finally {
            if (br != null) br.close();
        }

    java8中可以使用try-with-resources语句:

    try (BufferedReader br = new BufferedReader(new FileReader(path))) {
        return br.readLine();
    }

    对于网络连接和数据库连接等也要注意连接的关闭,如果采用了连接池,那关闭操作是由连接池负责的,程序中可以不用处理。

    2.4 将没有实现hashCode()和equals()方法的对象加入到HashSet中

    这是一个简单却很常见的场景。正常情况下Set会过滤重复的对象,但是如果没有hashCode() 和 equals()实现,重复对象会不断被加入到Set中,并且再也没有机会去移除。

    因此给类都加上hashCode() 和 equals()方法的实现是一个好的编程习惯。可以通过Lombok的@EqualsAndHashCode很方便实现这种功能。

    3. 查找内存泄漏的方法

    3.1 记录gc日志

    通过在jvm参数中指定-verbose:gc,可以记录每次gc的详细情况,用于分析内存的使用。

    3.2 进行profiling

    通过Visual VM或jdk自带的Java Mission Control,进行内存分析。

    3.3 代码审查

    通过代码审查和静态代码检查,发现导致内存泄漏问题的错误代码。

    4. 总结

    代码层面的检查可以帮助发现部分内存泄漏的问题,但是生产环境中的内存泄漏往往不容易提前发现,因为很多问题是在大并发场景下才会出现。因此还需要通过压力测试工具进行压力测试,提前发现潜在的内存泄漏问题。

    展开全文
  • 从与C/C 内存泄漏对比的角度分析了Java内存泄漏问题,详细介绍了Java内存泄漏的相关研究和工具,探讨了当前研究和工具中存在的不足并分析了其原因,总结了内存泄漏相关领域研究的发展趋势。
  • java程序内存泄漏排查

    2017-12-29 17:51:38
    有个java程序越跑越慢,如何排查? 首先通过jps找到java进程ID。然后top -p [pid]发现内存占用达到了最大值(-Xmx)。开始怀疑是由于频繁Full GC导致的,于是通过jstat -gcutil [pid] 60000查看GC的情况,其中...


    有个java程序越跑越慢,如何排查?

    首先通过jps找到java进程ID。然后top -p [pid]发现内存占用达到了最大值(-Xmx)。开始怀疑是由于频繁Full GC导致的,于是通过jstat -gcutil [pid] 60000查看GC的情况,其中60000表示每隔1分钟输出一次。果然是Full GC次数太多,JVM大部分时间都进行Full GC,而此时JVM会暂停其他一切工作,所以程序运行得非常慢。

    那到底的程序的哪一部分导致消耗了这么多的内存呢?通过jmap -histo:live [pid]查看进程中各种类型的对象创建了多少个,以及每种类型的对象占多少内存。当我看到有个对象被创建了5千多万个实例时,我就能定位到是哪儿的问题了。

    顺带说一下,通过jmap还可以生成JVM的内存dump文件,命令为jmap -dump:format=b,file=文件名 [pid],然后通过jhat命令在浏览器中查看,或者通过jvisualvm、eclipse memory analyzer等工具进行查看。使用jhat命令查看的方式为:jhat -J-Xmx1024M [file],等控制台输出Started HTTP server on port 7000. Server is ready.后在浏览器中输入ip:7000就可以查看各上类中各种实例被创建了多少个。

    展开全文
  • 虽然jvm有垃圾回收机制,如果程序编写不注意某些特定规则,仍然会导致java程序内存泄漏,最终可能出现OutOfMemory异常。 1.Java内存泄漏的原因 java中的对象从使用上分为2种类型,被引用(referenced)的和不被...

    虽然jvm有垃圾回收机制,如果程序编写不注意某些特定规则,仍然会导致java程序内存泄漏,最终可能出现OutOfMemory异常。

    1.Java内存泄漏的原因

    java中的对象从使用上分为2种类型,被引用(referenced)的和不被引用(unreferenced)的。垃圾回收只会回收不被引用的对象。被引用的对象,即使已经不再使用了,也不会被回收。因此如果程序中有大量的被引用的无用对象时,就是出现内存泄漏。

    2.java堆内存(Heap)泄漏

    jvm堆内存的大小是通过 -Xms 和 -Xmx两个参数指定的。

    2.1 对象被静态成员引用

    当大对象被静态成员引用时,会造成内存泄漏。

    示例:

    private Random random = new Random();
    
    public static final ArrayList<Double> list = new ArrayList<Double>(1000000);
    
    for (int i = 0; i < 1000000; i++) { list.add(random.nextDouble()); }
    

    ArrayList是在堆上动态分配的对象,正常情况下使用完毕后,会被gc回收,但是在此示例中,由于被静态成员list引用,而静态成员是不会被回收的,所以会导致这个很大的ArrayList一直停留在堆内存中。

    因此需要特别注意静态成员的使用方式,避免静态成员引用大对象或集合类型的对象(如ArrayList等)。

    2.2 String的intern方法

    在大字符串上调用String.intern() 方法,intern()会将String放在jvm的内存池中(PermGen ),而jvm的内存池是不会被gc的。因此如果大字符串调用intern()方法后,会产生大量的无法gc的内存,导致内存泄漏。

    如果必须要使用大字符串的intern方法,应该通过-XX:MaxPermSize参数调整PermGen内存的大小。

    2.3 读取流后没有关闭

    开发中经常忘记关闭流,这样会导致内存泄漏。因为每个流在操作系统层面都对应了打开的文件句柄,流没有关闭,会导致操作系统的文件句柄一直处于打开状态,而jvm会消耗内存来跟踪操作系统打开的文件句柄。 示例:

    BufferedReader br = new BufferedReader(new FileReader(path));
    return br.readLine();
    

    要解决这个问题,在java8之前的版本中可以在finally中加入关闭操作:

     BufferedReader br = new BufferedReader(new FileReader(path));
        try {
            return br.readLine();
        } finally {
            if (br != null) br.close();
        }
    

    java8中可以使用try-with-resources语句:

    try (BufferedReader br = new BufferedReader(new FileReader(path))) {
        return br.readLine();
    }
    

    对于网络连接和数据库连接等也要注意连接的关闭,如果采用了连接池,那关闭操作是由连接池负责的,程序中可以不用处理。

    2.4 将没有实现hashCode()和equals()方法的对象加入到HashSet中

    这是一个简单却很常见的场景。正常情况下Set会过滤重复的对象,但是如果没有hashCode() 和 equals()实现,重复对象会不断被加入到Set中,并且再也没有机会去移除。

    因此给类都加上hashCode() 和 equals()方法的实现是一个好的编程习惯。可以通过Lombok的@EqualsAndHashCode很方便实现这种功能。

    3. 查找内存泄漏的方法

    3.1 记录gc日志

    通过在jvm参数中指定-verbose:gc,可以记录每次gc的详细情况,用于分析内存的使用。

    3.2 进行profiling

    通过Visual VM或jdk自带的Java Mission Control,进行内存分析。

    3.3 代码审查

    通过代码审查和静态代码检查,发现导致内存泄漏问题的错误代码。

    4. 总结

    代码层面的检查可以帮助发现部分内存泄漏的问题,但是生产环境中的内存泄漏往往不容易提前发现,因为很多问题是在大并发场景下才会出现。因此还需要通过压力测试工具进行压力测试,提前发现潜在的内存泄漏问题。

    转载于:https://my.oschina.net/hiease/blog/1613871

    展开全文
  • linux程序内存泄漏排查一、前言 C/C++的内存操作一直是一种“诟病”,主要就是由于程序员调用API去操作内存的申请和释放,人不是完美的,所以会造成申请完内存不去释放的现象存在;但是内存只申请不释放,到了一定...

    linux程序内存泄漏排查


    一、前言

    C/C++的内存操作一直是一种“诟病”,主要就是由于程序员调用API去操作内存的申请和释放,人不是完美的,所以会造成申请完内存不去释放的现象存在;

    但是内存只申请不释放,到了一定的阶段,会造成我们的程序崩溃掉;

    一般我们生产程序跑的时候,我们需要监控内存变化,如果内存可使用大幅度下降,很大概率是由于内存泄漏导致的,这时候,我们需要去定位分析内存泄漏的原因和修复;


    二、案例

    测试案例:

    #include 

    using namespace std;

    void GetMemory(char* p,int num){
        p = new char[sizeof(char)*num];
    }

    int main(){
        char* str = NULL;
        while(1)
        {   
            GetMemory(str,100);
        }
        return 0;
    }

    我们使用前面介绍过的命令看一下,内存的变化:

    2a1d9423dc975fc5d4b19b328b3d0b15.png

    通过vmstat命令,我们可以知道free字段在逐渐减少,所以初步可以知道程序;

    三、查找内存泄漏

    1.valgrind

    这是一款开源内存检测的工具,里面包含了很多的工具,一般使用Memcheck这个工具偏多;

    Memcheck:这是valgrind应用最广泛的工具,一个重量级的内存检查器,能够发现开发中绝大多数内存错误使用情况,比如:使用未初始化的内存,使用已经释放了的内存,内存访问越界等。

    注:代码编译时我们要带上参数 -g,有了符号表才可以显示行号这些东西;

    测试代码就是我们上面的代码,我们把while循环注释掉,会更好演示;

    algrind --tool=memcheck --leak-check=full --show-reachable=yes --trace-children=yes ./tt其中–leak-check=full 指的是完全检查内存泄漏,

    –show-reachable=yes是显示内存泄漏的地点,

    –trace-children=yes是跟入子进程。

    结果:

    f482bdb53fa0b819ecbe6f1e44b32594.png

    我们会发现在第九行处出现了内存问题;


    2.mtrace

    mtrace能监测程序是否内存泄露

    mtrace需要包含头文件:

    #include 
    #include 

    步骤:

    1.设置环境变量

    setenv("MALLOC_TRACE", "output", 1);

    2.调用mtrace函数

    mtrace(); 

    代码:

    #include 
    #include 
    #include 

    using namespace std;

    int main(){
        setenv("MALLOC_TRACE""output"1);  
        mtrace(); 
        char* str = NULL;
        //while(1)
        {   
            char* p  =(char*)malloc(12);
        }
        return 0;
    }

    3.编译(带 -g)

    cmake_minimum_required (VERSION 2.8)

    project (C++)

    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")

    add_executable(tt test.cpp)

    4.运行

     ./tt

    5.查看目录下

    root@iZuf67on1pthsuih96udyfZ:~/C++/CMake/C++/Memory/build# ll
    total 60
    drwxr-xr-x 3 root root 4096 Apr 7 15:11 ./
    drwxr-xr-x 3 root root 4096 Apr 7 15:04 ../
    -rw-r--r-- 1 root root 11522 Apr 7 15:04 CMakeCache.txt
    drwxr-xr-x 5 root root 4096 Apr 7 15:04 CMakeFiles/
    -rw-r--r-- 1 root root 1369 Apr 7 15:04 cmake_install.cmake
    -rw-r--r-- 1 root root 4681 Apr 7 15:04 Makefile
    -rw-r--r-- 1 root root 313 Apr 7 15:11 output
    -rwxr-xr-x 1 root root 18992 Apr 7 15:04 tt*

    多了output文件

    6.使用mtrace命令,打开文件

    root@iZuf67on1pthsuih96udyfZ:~/# mtrace test output
    - 0x0000000001151c20 Free 3 was never alloc'd 0x7f863498ee9d
    - 0x0000000001151d10 Free 4 was never alloc'd 0x7f8634a5991f
    - 0x0000000001151d30 Free 5 was never alloc'd 0x7f8634ac923c

    Memory not freed:
    -----------------
    Address Size Caller
    0x00000000011521a0 0xc at /root/C++/CMake/C++/Memory/test.cpp:21

    最终检测到了在21行出现了内存泄漏;

    注:mtrace只能检测new是否有泄漏,但是不能定位在哪一行;


    四、总结

    作为一名合格的C/C++程序员,在编写程序的时候,我们需要牢记申请和释放内存,不然后造成想象不到的后果;


    想了解学习更多C++后台服务器方面的知识,请关注:微信公众号:====CPP后台服务器开发====


    扫码CPP后台服务器开发1a32b23020c2fc73edb75fc5580ecdb9.png5583231da6bdd2a9f960348e82ea4226.pngbee78c6bb1fe309987feb82bd239eda1.pnged33a92927606797490c078d41863ad5.gif4acb7979aeba2270be896df063db3324.gifa1a550efeb4368b55d1356388fdf08a4.png转载是一种动力 分享是一种美德
    展开全文
  • 相反,Java内存泄漏应当是每一个关心程序健壮性、稳定性和高性能的程序员所必须了解的知识。  本文将揭示什么时候需要关注内存泄漏以及如何进行防止。  摘要:Java 程序里也存在内存泄漏?当然。和流行的...
  • 摘要虽然Java虚拟机(JVM)及其垃圾收集器(garbage collector,GC)负责管理大多数的内存任务,Java软件程序中还是有可能出现内存泄漏。实际上,这在大型项目中是一个常见的问题。避免内存泄漏的第一步是要弄清楚它是...
  • 摘要虽然Java虚拟机(JVM)及其垃圾收集器(garbage collector,GC)负责管理大多数的内存任务,Java软件程序中还是有可能出现内存泄漏。实际上,这在大型项目中是一个常见的问题。避免内存泄漏的第一步是要弄清楚它是...
  • Java内存泄漏解释内存泄漏: 存在一些被分配的对象,满足两个特点:对象是可达的:在有向图中,存在通路与之相连.对象是无用的:程序以后不再使用这些对象.结果:消耗越来越多的内存资源,最终导致OutOfMemoryError。与C++...
  • 当计算机程序消耗内存但无法将其释放回操作系统时,就会发生计算机科学中的内存泄漏(在此情况下为泄漏)。 JVM在启动时将堆保留为虚拟内存,并且直到退出后才将其归还。 该虚拟内存在使用时会变成主内存。 这...
  • 内存泄漏是指java应用的堆内存使用率持续升高,直至内存溢出。 内存泄漏的的原因可能有多种 分配给应用程序的内存本身过小。而应用的业务代码,确实需要生成大量的对象 代码bug,某些需要被回收的对象,由于代码bug...
  • 内存泄漏是指java应用的堆内存使用率持续升高,直至内存溢出。 内存泄漏的的原因可能有多种 分配给应用程序的内存本身过小。而应用的业务代码,确实需要生成大量的对象 代码bug,某些需要被回收的对象,由于代码bug...
  • 一、什么是内存泄漏开发中,都能遇到或者听过两种关于java内存的异常情况:内存溢出(out of memory)和内存泄漏(memory leak)。内存溢出指的是程序需要申请新的内存时,没有足够大小的内存空间供其使用。常见类型:1...
  • Java内存泄漏

    2019-12-16 15:35:32
    (学习笔记)Java内存泄漏 关键词:java内存泄漏 内存泄漏定义 传统定义:一个对象不再被程序使用,但它所占用的内存没有得到及时的释放,导致内存使用量随着时间不断增加,最终导致程序崩溃。 Java内存泄漏java...
  • 所谓内存泄露就是指一个不再被程序使用的对象或变量一直被占据在内存中。java中有垃圾回收机制,它可以保证一对象不再被引用的时候,即对象编程了孤儿的时候,对象将自动被垃圾回收器从内存中清除掉。由于Java 使用...
  • JAVA内存泄漏原因和内存泄漏检测工具摘要虽然Java虚拟机(JVM)及其垃圾收集器(garbage collector,GC)负责管理大多数的内存任务,Java软件程序中还是有可能出现内存泄漏。实际上,这在大型项目中是一个常见的问题。...
  • 因此,很多程序员认为Java不存在内存泄漏问题,或者认为即使有内存泄漏也不是程序的责任,而是GC或JVM的问题。其实,这种想法是不正确的,因为Java也存在内存泄露,但它的表现与C++不同。 随着越来越多的服...
  • Java程序内存泄漏的问题吗?对这篇文章关注的人,一定知道我所指的内存泄漏是什么。一个Java程序运行结束后,退出时,虚拟机会回收所有的资源,包括内存。从这个角度讲Java是不会泄漏内存的(C语言就没有那么幸运...
  • Java平台的一个突出的特性是自动内存管理。很多人把这种特性误读为Java没有内存泄露。然而,在我印象中,现代Java框架以及基于Java的平台并非如此。特别是Android平台,能举出很多反例。为了让大家对Java平台的内存...
  • 但是,情况没有那么简单,因为Java应用程序中经常发生内存泄漏。本教程说明什么是内存泄漏,为什么会发生内存泄漏,以及如何防止内存泄漏。1. 什么是内存泄漏内存泄漏的定义:应用程序不再使用对象,但是垃圾收集器不...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,987
精华内容 1,594
关键字:

java程序内存泄漏

java 订阅