内存泄漏

JAVA应用CPU占用100%|内存泄漏分析总结

流过昼夜 提交于 2019-11-28 09:56:07
问题现象 vrs后台系统从某一时间点,根据已查结果,追溯到几个月前上线的PGC审核功能引起。 近期大概一周左右运营使用时会反馈系统访问越来越来慢,最终系统崩溃,无法访问。因为之前媒资每周都会有功能上线,把这个问题覆盖掉了,未能很快暴露出来。 实际上,通过Zabbix观察监控cpu、swap占用都是比较高的。 1031问题分析之CPU 100% 10-31日出现过一次问题,服务器上执行top命令按键1观察始终有一个cpu占用总100%,怀疑可能是因后台服务请求过多CPU繁忙导致访问慢。 将后台服务切到备机,通过堆栈分析具体那段代码引起的CPU占用100%问题。 问题定位过程: 1)jps -m 非常方便直接定位所有的Java进程pid [root @cdn ldw]# jps -m | grep 28081 6687 WatchdogManager start -conf /ldw/conf/resin/resin-mms-webapp-28081.xml --log-directory /ldw/apps/resin/log 6734 Resin --root-directory /ldw/apps/resin/ -conf /ldw/conf/resin/resin-mms-webapp-28081.xml -server default -socketwait 15304

垃圾回收机制

筅森魡賤 提交于 2019-11-28 08:17:44
Python GC主要使用 引用计数 来跟踪和回收垃圾。在引用计数的基础上,通过 标记-清除 解决容器对象可能产生的循环引用问题,通过 分代回收 以空间换时间的方法提高垃圾回收效率。 Python采用的是引用计数机制为主,标记-清除和分代收集两种机制为辅的策略。 引用计数 PyObject是每个对象必有的内容,其中 ob_refcnt 就是引用计数。当一个对象有新的引用时,它的 ob_refcnt 就会增加,当引用它的对象被删除,它的 ob_refcnt 就会减少。引用计数为0时,该对象生命就结束了。 通过使用内置的模块 sys.getrefcount() 可以查看对象的引用计数,但是会比正常计数大1。因为调用函数的时候需要传入对象使得其引用计数增加1。 增加引用计数:对象被创建、对象被引用、对象被作为参数传入到一个函数中、对象作为一个元素存储在容器中 减少引用计数:对象的别名被显示销毁、对象的别名被赋予新的对象、一个对象离开了它的作用域、对象所在的容器被销毁后从容器中删除对象 一个误区:Python系统维护着一个常见的 整数常量池 ,即 -5~255 ,在这个区间的数字会有其他的处理方式。包括字符串也有一些特殊的处理,所以在使用应用技术的时候,最好是使用自己自定义的数据类型,这样方便分析。 import sys nu = 10 print ( sys . getrefcount

Jvm内存泄漏

∥☆過路亽.° 提交于 2019-11-27 20:51:39
内存泄漏和内存溢出的关系 内存泄露:指程序中动态分配内存给一些临时对象,但是对象不会被GC所回收,它始终占用内存。即被分配的对象可达但已无用。 内存溢出:指程序运行过程中无法申请到足够的内存而导致的一种错误。内存溢出通常发生于OLD段或Perm段垃圾回收后,仍然无内存空间容纳新的Java对象的情况。 从定义上可以看出内存泄露是内存溢出的一种诱因,但是不是唯一因素。 可以使用Runtime.getRuntime().freeMemory()进行内存泄漏查询 Runtime.getRuntime().freeMemory()表示当前还有多少空闲内存 package com.one.util; public class Hello { public static void main(String[] args) { System.out.println("free内存:" + Runtime.getRuntime().freeMemory() / 1024 / 1024); String[] aaa = new String[2000000]; for (int i = 0; i < 2000000; i++) { aaa[i] = new String("aaa"); } System.out.println("free内存:" + Runtime.getRuntime()

android事件通信方案对比与LiveDataBus详解

萝らか妹 提交于 2019-11-27 16:08:49
事件通信 定义:Activity、fragment、Service、Provider之间进行信息的传递和交换 通信方案比较 通信方案 优点 缺点 handler 系统原生,能实现线程间通信 高耦合 不利于维护 容易导致内存泄漏和空指针 broadcast 简单 性能差 传播数据有限 打乱代码的执行逻辑 interface 速度快,容易理解 实现复杂,不利于维护 rxBus 效率高,无内存泄漏 基于rxjava,学习成本高且依赖包太大,rxjava2.2M EventBus 使用简单 混淆问题 无法感知组件生命周期 实现复杂 LiveDataBus 实现极其简单 代码量少 官方提供稳定的依赖代码 感知组件生命周期 不存在内存泄漏 从上面对比可以看出,LiveDataBus是最优方案,那么接下来我们详细介绍LiveDataBus LiveDataBus LiveDataBus,是基于LiveData,利用发布订阅模式来实现的事件通信方案,那么我们就要解决以下几个问题 什么是发布订阅模式 什么是LiveData 如何构建LiveDataBus 什么是发布订阅模式 它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。 发布订阅模式和观察者模式的区别 在观察者模式中,观察者是知道Subject的,Subject一直保持对观察者进行记录。然而

Golang内存泄漏问题和处理方法

喜欢而已 提交于 2019-11-27 13:23:16
1、给系统打压力,内存占用增大,但停止打压后,内存不能降低,则可能有内存泄漏。 2、top不能实时反映程序占用内存,因Go向系统申请内存不使用后,并不立即归还系统。 3、程序占用系统内存、Go的堆内存、实际使用内存:从系统申请的内存会在Go的内存池管理,整块的内存页,长时间不被访问并满足一定条件后,才归还给操作系统。又因为有GC,堆内存也不能代表内存占用,清理过之后剩下的,才是实际使用的内存。 4、调用runtime.ReadMemStats可以看到Go的内存使用信息 5、使用go tool pprof -inuse_space http://127.0.0.1:6060/debug/pprof/heap?debug=2得到更细信息,其中HeapInuse为实际内存使用量 6、第一条原则是,绝对不能由消费者关channel,因为向关闭的channel写数据会panic。正确的姿势是生产者写完所有数据后,关闭channel,消费者负责消费完channel里面的全部数据 func produce(ch chan<- T) { defer close(ch) // 生产者写完数据关闭channel ch <- T{} } func consume(ch <-chan T) { for _ = range ch { // 消费者用for-range读完里面所有数据 } } ch :=

内存溢出和内存泄漏的区别

老子叫甜甜 提交于 2019-11-27 11:08:10
内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。 内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。 memory leak会最终会导致out of memory! 内存溢出就是你要求分配的内存超出了系统能给你的,系统不能满足需求,于是产生溢出。 内存泄漏是指你向系统申请分配内存进行使用(new),可是使用完了以后却不归还(delete),结果你申请到的那块内存你自己也不能再访问(也许你把它的地址给弄丢了),而系统也不能再次将它分配给需要的程序。一个盘子用尽各种方法只能装4个果子,你装了5个,结果掉倒地上不能吃了。这就是溢出!比方说栈,栈满时再做进栈必定产生空间溢出,叫上溢,栈空时再做退栈也产生空间溢出,称为下溢。就是分配的内存不足以放下数据项序列,称为内存溢出. 以发生的方式来分类,内存泄漏可以分为4类: 1. 常发性内存泄漏。发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。 2. 偶发性内存泄漏。发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的。对于特定的环境

auto_ptr

南笙酒味 提交于 2019-11-27 01:25:45
1、   int *pi = new int(1024);   delete pi; // 释放pi指向的int对象占用的内存空间   pi = 0; // 将pi设置为0,不指向任何东西,为Null   注意:删除0值的指针是安全的,但是没有任何意义。对于上面的情况,先释放内存,再置为Null。顺序不能颠倒,如果颠倒了,会导致内存泄漏。 2、在Stack上分配的内存,用完后,系统会自动释放,调用析构方法。在Heap上,通过new分配内存,必须使用delete,手动释放内存,如果忘记,会导致内存泄漏。如果重复释放内存,会破坏自由存储区,导致分配在上面的其他对象受到破坏。(Stack记录程序的执行过程,Heap存放数据) 3、为了解决上面的问题,使用auto_ptr 4、auto_ptr是一个模版类,对一个类型的指针进行封装,把delete操作放在析构方法中,由于析构方法总是被调用,就保证了内存不会泄露。 5、auto_ptr是一个模版类,为了让auto_ptr使用起来像一个指针,重载*与->操作符。 6、用a对象copy构造b对象的时候,要把a的指针设为0,为什么?   如果,不把a的指针设为0,a,b都会在析构方法中进行delete,导致重复释放。 7、把a对象copy赋值给b对象的时候,首先要把b对象的指针delete,然后把a的指针设为0,为什么?   b的指针指向了a的指针

内存泄漏

喜夏-厌秋 提交于 2019-11-27 01:25:15
1、程序结束后,程序(实际上是指进程)占用的内存全部释放,不管是栈上的内存还是堆上的内存,包括泄漏的内存,全部释放。因为进程都不在了,OS会把进程的所有资源回收。 2、因此,所谓的内存泄漏只是存在于程序运行过程中。 3、内存泄漏:在程序运行过程中,对于一块确定不再使用的内存,没有人工delete,才会造成内存泄漏。 4、假设一块内存,在程序的整个运行过程中都要使用,这种情况下这块内存是不能释放的,否则会引起未定义行为。必须等到程序结束后,OS来回收内存。 5、假设指针指向一块申请的内存A,然后再指向一块申请的内存B,对于内存A,以后永远不会在使用,没有对内存A进行delete,造成内存泄漏。OS不会释放内存A,因为他不知道你还用不用内存A。只有在程序结束的情况下,才会释放进城上的所有内存,包括内存A。 转载于:https://www.cnblogs.com/nzbbody/p/3397550.html 来源: https://blog.csdn.net/weixin_30718391/article/details/99234478

获取集合的方法

左心房为你撑大大i 提交于 2019-11-27 01:24:45
考虑下面的需求,从配置文件中,读取一些数据,这些数据放到一个集合中,获取集合,使用方法A,完成任务。该怎么做? 1、首先明确一点,坚决不能让A返回引用。 2、方法A在栈上创建集合,返回集合。不存在内存泄漏的问题,但是要付出copy代价。 3、方法A在堆上创建集合,返回集合的指针,copy代价很低,但是会存在内存泄漏的问题。 4、主调方法创建一个集合,把集合的引用传递给被调方法A,A修改集合的内容。这个不直观,客户要一些东西,方法A要求客户准备一个容器,A在容器中填充内容。 5、采用哪种方法,要看具体的使用场景,如果集合内容很小,copy代价小,就不要用指针,否者用指针。 6、还要考虑另外一种情况,返回的集合是要客户维护,还是A维护。比如,客户在一个循环中,每次都需要集合,这就会导致A重复读取配置文件。解决这个问题的办法是:客户在循环之前,先把集合保存起来。但是,考虑下面的情况,程序中很多地方,不同的客户,都需要这个集合,那么方法A应该维护集合,读取一次,内部保存起来,下次客户再申请,直接返回就行了。这就意味着,程序运行过程中,集合的内存是不能释放的,可以使用指针,为了避免内存泄漏,可以使用智能指针。 转载于:https://www.cnblogs.com/nzbbody/p/3411215.html 来源: https://blog.csdn.net/weixin_30371875

Java内存泄漏与内存溢出

Deadly 提交于 2019-11-26 19:11:24
内存泄漏—内存溢出 一、内存泄漏: (1)概念:分配给对象的内存无法进行回收,造成资源浪费,终有一日会导致内存资源耗尽,内存溢出。 (2)场景:循环创建对象、连接没有关闭(数据库连接、网络连接、IO流等)、 (3)如何避免:及时关闭连接、尽量使用StringBuilder\StringBuffer 、减少静态变量(存放在方法区)等 二、内存溢出 (1)概念:OutOfMemory,程序申请的内存超过了系统分配的能力。 (2)场景:内存泄漏积累一定时间导致资源耗尽无法分配新内存、申请对象内存过大。加载类过多、递归调用太深等 (3)程序申请新内存: 来源: https://blog.csdn.net/qq_43251445/article/details/99048584