内存泄漏

Linux 内存管理三

让人想犯罪 __ 提交于 2020-02-01 19:39:33
本节主要涉及下面这些概念,搞清楚我们在linux下面写一个应用程序究竟耗费了多少内存,也是我们查内核泄漏的指标。 VSS- Virtual Set Size RSS- Resident Set Size PSS- Proportional Set Size USS- Unique Set Size 在linux 里面大量的存在内存共享的概念,比如我们的libc 库,加入我们有100个程序调用了c 库,linux会把代码段再内存里面共享给这个100个进程使用(动态连接库都是这样),我们把一个程序跑两次,程序的代码段也是共享的,当然数据段是写时拷贝的,当我们再评估一个进程耗费多少内存的时候,我们有必要搞清这些虚的,实的,以及共享的,我们说的进程的内存消耗就是指用户空间耗费的内存,内核空间耗费的内存就是内核消耗的,比如我们做了一个系统调用,这个系统调用申请了很多内存,这个写内存也不属于进程消耗 VMA 表面地址的合法性,和权限,不代表页表里面真实的权限,但是linux的页表中发生page fault时会检测vma,确定是否合法访问,如果合法,申请对应的物理地址映射过来。 这些vma 可能来自程序本身的代码段,数据段,或者动态库。 我们一般用如下方法来查看vma Linux 下各种page fault,通常分为minor page fault ,和major page fault

常见的内存问题分析思路

僤鯓⒐⒋嵵緔 提交于 2020-02-01 00:09:12
一 系统内存不足 Java 应用一般都有单机或者集群的内存水位监控,如果单机的内存利用率大于 95%,或者集群的内存利用率大于80%,就说明可能存在潜在的内存问题(注:这里的内存水位是系统内存)。 除了一些较极端的情况,一般系统内存不足,大概率是由 Java 应用引起的。使用 top 命令时,我们可以看到 Java 应用进程的实际内存占用,其中 RES 表示进程的常驻内存使用,VIRT 表示进程的虚拟内存占用,内存大小的关系为:VIRT > RES > Java 应用实际使用的堆大小。除了堆内存,Java 进程整体的内存占用,还有方法区/元空间、JIT 缓存等,主要组成如下: Java 应用内存占用 = Heap(堆区)+ Code Cache(代码缓存区) + Metaspace(元空间)+ Symbol tables(符号表)+ Thread stacks(线程栈区)+ Direct buffers(堆外内存)+ JVM structures(其他的一些 JVM 自身占用)+ Mapped files(内存映射文件)+ Native Libraries(本地库)+ ... Java 进程的内存占用,可以使用 jstat -gc 命令查看,输出的指标中可以得到当前堆内存各分区、元空间的使用情况。堆外内存的统计和使用情况,可以利用 NMT(Native Memory

day2

 ̄綄美尐妖づ 提交于 2020-01-28 23:57:21
1 . java的内存泄漏 ,指一个不再被程序使用的对象或变量一直占据在内存中,并且不能被GC回收(该释放的对象没有被释放)。 常见情况:(1)各种连接并没有调用关闭方法(例如数据库的连接),使用监听器,释放对象时,忘记删除监听器。 (2)长生命周期对象持有短生命周期的引用。例如: public class Test(){ Object object; public void method(){ object=new Object(); } } object容易产生内存泄漏,调用method方法,不能释放object对象,解决方法一:将object当做局部对象,放入method方法中。解决方法二:在method方法中,最后一行加入如下代码:object=null; (3)静态集合类的引用(HashMap、Vector的引用) static Vector v=new Vector(5); for(int i=0;i<5;i++){ Object object=new Object(); v.add(object); object=null; } 静态成员变量v的存在周期跟程序运行时间一致,object不能被释放,因为它一直被vector引用着,仅仅释放Object也无用(object=null),因为一直调用v.add(object),GC机制不能回收

【C语言进阶剖析】42、内存操作的经典问题分析(二)

梦想的初衷 提交于 2020-01-28 17:11:54
1 常见内存错误 结构体成员指针未初始化 结构体成员指针未分配足够的内存 内存分配成功,但未初始化 内存操作越界 我们记得定义一个指针的时候要初始化,却容易忘记定义结构体变量时初始化指针成员。指针未分配足够的内存会导致越界操作的问题。内存分配成功,但未初始化,这个可能回造成字符串方面的错误。内存操作越界可能会操作不因该操作的内存,比如字符串没有结尾的 ‘\0’,复制的时候没有发现结尾的 ‘\0’,导致越界了。第四条包括的 2,3 条。 2 找内存错误 下面我们来找找下面的程序中哪里出现了内存错误呢? // 42-1.c # include <stdio.h> # include <malloc.h> void test ( int * p , int size ) { int i = 0 ; for ( i = 0 ; i < size ; i ++ ) { printf ( "%d\n" , p [ i ] ) ; } free ( p ) ; } void func ( unsigned int size ) { int * p = ( int * ) malloc ( size * sizeof ( int ) ) ; int i = 0 ; if ( size % 2 != 0 ) { return ; } for ( i = 0 ; i < size ; i ++ ) {

内存泄漏和内存溢出详解

瘦欲@ 提交于 2020-01-28 08:29:19
内存泄漏(Memory Leak) 概念 程序已动态申请的堆内存,由于某种原因程序未释放或无法释放,造成程序内存的浪费,导致系统运行速度减慢甚至系统崩溃等严重后果。 内存泄漏的根本原因是: 长生命周期的对象,持有短生命周期对象的引用 ,尽管短生命周期的对象已经不再需要,单因为长生命周期的对象持有它的引用而导致不能被GC回收。 发生条件 内存泄漏必须满足以下两个条件 对象是可达的。即在有向图中,存在通道达到该对象,GC不会回收 对象是无用的。即程序以后不会再使用该对象 发生场景 静态集合类引起内存泄漏 HashMap、Vactor等集合的使用最容易出现内存泄漏。因为这些集合属于静态集合,这些静态变量的生命周期和应用程序一致,他们所引用的所有Object对象都不能被释放,因为这些对象还一直被Vector引用着 Static Vector v = new Vector ( 10 ) ; for ( int i = 1 ; i < 100 ; i ++ ) { Object o = new Object ( ) ; //每次创建新的对象 v . add ( o ) ; o = null ; //将对象添加到集合后将对象的引用置空 } //因为对象的引用置空之后,JVM已经失去的使用该对象的价值,本应该被GC清除,但是在vector集合中还存在着此对象的引用,导致没能顺利清除

Android中的WeakReference 弱引用

≯℡__Kan透↙ 提交于 2020-01-26 16:28:23
WeakReference 弱引用 定义:弱引用,与强引用(我们常见的引用方式)相对;特点是:GC在回收时会忽略掉弱引用对象(忽略掉这种引用关系),即:就算弱引用指向了某个对象,但只要该对象没有被强引用指向,该对象也会被GC检查时回收掉。 强引用实例自然不会被GC回收! 如何引出弱引用?弱引用的实际用途是什么? 什么是内存泄漏?Java使用有向图机制,通过GC自动检查内存中的对象;如果GC发现一个或一组对象为不可达的状态,则将该对象从内存中回收。也就是说:一个对象不被任何引用所指向,则该对象会在被GC发现的时候回收。 可能导致内存泄漏的实例: Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { mImageView.setImageBitmap(mBitmap); }; }; 当使用内部类(或者匿名类)来创建Handler的时候,Handler对象会隐式地持有一个外部类的对象(通常是Activity)的引用(否则怎么可能通过Handler来操作Activity的View?)。而Handler通常会伴随着一个耗时的后台线程(比如:拉取网络图片);该后台线程在任务执行完毕后,通过消息机制通知Handler,然后Handler把图片更新到界面上

valgrind内存泄露检测工具

你离开我真会死。 提交于 2020-01-22 14:45:34
一、安装 valgrind linux环境首先进入root用户 然后执行下面的命令 tar -jxvf valgrind-3.12.0.tar.bz2 cd valgrind-3.12.0 ./configure make make install valgrind --version 查看valgrind 版本,并且验证是否安装成功 二、查看内存泄漏示例 #include <iostream> using namespace std; int main() { char *p = new char[10]; *p = 'a'; *p++ = 'b'; cout << p << endl; return 0; } g++ -g -o core main.cpp valgrind --leak-check=yes --show-reachable=yes --log-file=a.log ./core valgrind --leak-check=full --show-reachable=yes --log-file=a.log ./shdaily.fcgi "op=search&date=2011-04-14&current=4" --tool=memcheck //使用valgrind的memcheck功能 -show-reachable=yes //是否检测控制范围之外的泄漏

13.ThreadLocal

放肆的年华 提交于 2019-12-30 23:36:26
ThreadLocal类型的变量为线程本地变量,大概的原理就是建立了一个Map,然后key是线程,value是指,通过get方法就能取到每个线程自己的变量副本 1. ThreadLocal使用 2. ThreadLocal源码分析 public class ThreadLocal<T> { // 设置属性 public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); // 找到当前线程里的map if (map != null) map.set(this, value); // 将 键值对 threadLocal的this 和 value 放入到当前线程的map中 else createMap(t, value); } // 获取属性 public T get() { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); // 获取map if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); // 通过 threadLocal的this 获取到value if (e != null) {

Linux C/C++ Memory Leak Detection Tool

北城余情 提交于 2019-12-28 13:20:41
目录 1. 内存使用情况分析 2. 内存泄漏(memory leak) 3. Valgrind使用 1. 内存使用情况分析 0x1: 系统总内存的分析 可以从proc目录下的meminfo文件了解到当前系统内存的使用情况汇总,其中 可用的物理内存 = memfree + buffers + cached 当memfree不够时,内核会通过回写机制(pdflush线程)把cached和buffered内存回写到后备存储器,从而释放相关内存供进程使用,或者通过手动方式显式释放cache内存: echo 3 > /proc/sys/vm/drop_caches $cat /proc/meminfo MemTotal: 8388608 kB MemFree: 6880760 kB Buffers: 0 kB Cached: 1490828 kB SwapCached: 0 kB Active: 1224960 kB Inactive: 282832 kB Active(anon): 17028 kB Inactive(anon): 348 kB Active(file): 1207932 kB Inactive(file): 282484 kB Unevictable: 0 kB Mlocked: 4884 kB SwapTotal: 1999864 kB SwapFree:

java内存泄漏的定位与分析

試著忘記壹切 提交于 2019-12-28 13:20:16
1、为什么会发生内存泄漏 java 如何检测内在泄漏呢?我们需要一些工具进行检测,并发现内存泄漏问题,不然很容易发生down机问题。 编写java程序最为方便的地方就是我们不需要管理内存的分配和释放,一切由jvm来进行处理,当java对象不再被应用时,等到堆内存不够用时,jvm会进行垃圾回收,清除这些对象占用的堆内存空间,如果对象一直被应用,jvm无法对其进行回收,创建新的对象时,无法从Heap中获取足够的内存分配给对象,这时候就会导致内存溢出。而出现内存泄露的地方,一般是不断的往容器中存放对象,而容器没有相应的大小限制或清除机制。容易导致内存溢出。 当服务器应用占用了过多内存的时候,如何快速定位问题呢?现在,Eclipse MAT的出现使这个问题变得非常简单。EclipseMAT是著名的SAP公司贡献的一个工具,可以在Eclipse网站下载到它,完全免费的。 要定位问题,首先你需要获取服务器jvm某刻内存快照。jdk自带的jmap可以获取内存某一时刻的快照,导出为dmp文件后,就可以用Eclipse MAT来分析了,找出是那个对象使用内存过多。 2、内存泄漏的现象: 常常地,程序内存泄漏的最初迹象发生在出错之后,在你的程序中得到一个OutOfMemoryError。这种典型的情况发生在产品环境中,而在那里,你希望内存泄漏尽可能的少,调试的可能性也达到最小