精华内容
下载资源
问答
  • python内存不释放

    千次阅读 2019-07-26 21:26:59
    在maillist里面看到无数次的有人问,python速度为什么这么慢,python内存管理很差。实话说,我前面已经说过了。如果你在意内存/CPU,不要用python,改用C吧。...不过今天还是说说,python的内存为什么不释放。 ...

    转载地址:https://blog.csdn.net/shaququ/article/details/52100434

    在maillist里面看到无数次的有人问,python速度为什么这么慢,python内存管理很差。实话说,我前面已经说过了。如果你在意内存/CPU,不要用python,改用C吧。就算C不行,起码也用个go或者java。不过今天还是说说,python的内存为什么不释放。

     

    首先,python的初始内存消耗比C大,而且大很多。这个主要来自python解释器的开销,没什么好解释的。用解释器,就得承担解释器运行开销。然后,python中的每个对象,都有一定的对象描述成本。因此一个long为例,在C下面一般是4个字节(不用int是因为int在不同平台下是变长的),而python下面至少是16个字节。如果你生成100W个对象,那么C的内存消耗是4M,python的是16M。这些都是常规内存消耗,搞不明白的就别问了,不再解释。

    下面解释一下python的内存释放情况。

    如果是C,通常是用long array[1024 * 1024]的方法来生成1M个对象空间。当然,实际这样是不一定能运行的。因为linux的默认栈空间是8M,而Windows默认栈空间只有1M。所以代码在linux下可以通过,而windows下会跑爆掉。怎么办?下面说。当这个函数执行完毕后,当RET的时候,会自动退栈,空间就会自动释放掉(虽然在逻辑上这部分空间还是保留没有释放的,然而空间不活跃了,不过统计的时候还是占用的)。当然,更好的办法是使用malloc。malloc会从系统中自动提取和管理空间,free自动释放。这样无论是linux还是windows,都没有栈空间不足的问题。free后就会自动交还系统(4M已经超过了交还的最大阀值,一般glibc不会自己闷掉不交给系统的)。如果你忘记free,这部分内存就会一直占用,直到进程退出未知,这就是很有名的内存泄露。

    python下的情况更加复杂一些,python没有直接使用malloc为对象分配细粒度内存,而是使用了三层堆结构,加上三色标记进行回收。所谓三层堆,细节我们不说了,在源码阅读笔记里面写的比较详细。但是有一点需要我们记住的——当我们分配某个大小的内存的时候,内存管理器实际上是向上对齐到8字节,然后去对应的内存池中切一块出来用的。也就是说,如果我们运气比较差,申请了10个对象,偏偏每个对象大小差8字节。这样系统就要给我们分配10个堆,而不是刚刚好。如果你的对象粒度都比较散,那么内存开销比较大也不奇怪。

    python下还有一个更坑爹的事情,也是大部分内存不释放的根本原因。在int/str等对象的模块中,有个模块级别的对象缓存链表,static PyObject * free_list。当对象释放的时候,压根不会还到池中,而是直接在free_list中缓存。根据我的搜索,python内部没有地方对此进行干预。就是说,一旦你真的生成了1M个数字对象,然后释放。这1M个对象会在free_list链表中等待重用,直到天荒地老,这16M内存压根不会返还。而且,int的对象缓存链表和str的还不通用。如果你又做了1M个str对象,他的开销还是会继续上涨。几乎所有的内建对象都有这种机制,因此对于大规模对象同时生成,python会消耗大量内存,并且永不释放。

    解决的机制,基本只有用yield来将列表对象转换为生成器对象。列表对象会同时生成所有元素,从而直接分配所有内存。而生成器则是一次生成一个元素,比较节约内存。
     

    展开全文
  • 公司CMS的tomcat又挂掉了,...出现以下错误,后来把tomcat的内存增大到1024 严重:Exceptioninitializingpagecontext java.lang.OutOfMemoryError:Javaheapspace 在tomcat\bin\catalina.bat的setCURRENT_DIR=%cd%前面添

    公司的tomcat又挂掉了,之前挂了一次.出现以下错误,后来把tomcat的内存增大到1024  
    严重: Exception initializing page context  java.lang.OutOfMemoryError: Java heap space  
       
      在tomcat\bin\catalina.bat的set CURRENT_DIR=%cd% 前面添加  
          set JAVA_OPTS =-Xms512m -Xmx1024m  
          意思:设置最小虚拟内存512,最大1024.  
      今天tomcat又挂了,一查之下,发现内存只升不降,久而久之,系统就挂死了.另外你可以用java的一个管理工具查看内存使用情况.在jdk1.6.0\bin\jconsole.exe.  
       
       总结下内存只升不降的几个原因:  

       1.在java中虽然有垃圾回收器,但是对rs等通过jdbc访问数据库的所产生的垃圾,它并不回收!  
        2.是否是循环套接层数太多导致资源得不到释放,或者存在死循环,后者的可能性恨大。  

         解决方法是让tomcat自己管理内存,在startup.bat的@echo off下面添加以下代码:  

    set JAVA_OPTS=%JAVA_OPTS% 
    
    -Dcom.sun.management.jmxremote.port=1090 
    
    -Dcom.sun.management.jmxremote.ssl=false 
    
    -Dcom.sun.management.jmxremote.authenticate=false 
    
    -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager 
    
    -Djava.util.logging.config.file="%CATALINA_HOME%\conf\logging.properties"  



         然后再启动startup.bat,tomcat就会自己管理内存了.  
          
         另外事实上,这是一个优化。因为对于操作系统,请求内存的系统调用会占用大量的cpu时间,所以频繁的请求、释放内存将会导致性能的严重下降。所以对于 jvm,最好的方式就是尽量多占用内存作为heap,少释放甚至不释放空闲的heap给操作系统以减少消耗在内存请求、释放操作上的cpu时间。  
        

    改正方法:-Xms256m -Xmx256m -XX:MaxNewSize=256m -XX:MaxPermSize=256m 

    ---------------------------------------------------------------------------------------------------------------------------------

    先试试这个:
    -Xms64m 
    -Xmx256m 
    -XX:PermSize=128M 
    -XX:MaxNewSize=256m 
    -XX:MaxPermSize=256m   



    2、其次是:java.lang.OutOfMemoryError: PermGen space 

    原因: 

    PermGen space的全称是Permanent Generation space,是指内存的永久保存区域,这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中,它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的应用中有很CLASS的话,就很可能出现PermGen space错误,这种错误常见在web服务器对JSP进行pre compile的时候。如果你的WEB APP下都用了大量的第三方jar, 其大小超过了jvm默认的大小(4M)那么就会产生此错误信息了。 

    解决方法: 

    1. 手动设置MaxPermSize大小 
    修改TOMCAT_HOME/bin/catalina.bat(Linux下为catalina.sh),在Java代码 
    “echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行:    
    set JAVA_OPTS=%JAVA_OPTS% -server -XX:PermSize=128M -XX:MaxPermSize=512m   

    “echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行: 
    set JAVA_OPTS=%JAVA_OPTS% -server -XX:PermSize=128M -XX:MaxPermSize=512m 

    catalina.sh下为: 
    Java代码 
    JAVA_OPTS="$JAVA_OPTS -server -XX:PermSize=128M -XX:MaxPermSize=512m"  

    JAVA_OPTS="$JAVA_OPTS -server -XX:PermSize=128M -XX:MaxPermSize=512m" 

     

    展开全文
  • Spring Boot1.x 内存上涨不释放

    千次阅读 2019-02-28 10:26:01
    1. 查看原因,发现配置了4G堆内内存,但是实际使用的物理内存竟然高达7G,确实正常。JVM参数配置是“-XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -XX:+AlwaysPreTouch -XX:ReservedCodeCacheSize=128m -XX:...

    1.  查看原因,发现配置了4G堆内内存,但是实际使用的物理内存竟然高达7G,确实不正常。JVM参数配置是“-XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -XX:+AlwaysPreTouch -XX:ReservedCodeCacheSize=128m -XX:InitialCodeCacheSize=128m, -Xss512k -Xmx4g -Xms4g,-XX:+UseG1GC -XX:G1HeapRegionSize=4M”
     

    2.  为什么堆外内存没有释放掉呢?
    虽然问题已经解决了,但是有几个疑问:

    为什么使用旧的框架没有问题?
    为什么堆外内存没有释放?
    为什么内存大小都是64M,JAR大小不可能这么大,而且都是一样大?
    为什么gperftools最终显示使用的的内存大小是700M左右,解压包真的没有使用malloc申请内存吗?
    带着疑问,笔者直接看了一下Spring Boot Loader那一块的源码。发现Spring Boot对Java JDK的InflaterInputStream进行了包装并且使用了Inflater,而Inflater本身用于解压JAR包的需要用到堆外内存。而包装之后的类ZipInflaterInputStream没有释放Inflater持有的堆外内存。于是笔者以为找到了原因,立马向Spring Boot社区反馈了这个bug。但是反馈之后,笔者就发现Inflater这个对象本身实现了finalize方法,在这个方法中有调用释放堆外内存的逻辑。也就是说Spring Boot依赖于GC释放堆外内存。

    笔者使用jmap查看堆内对象时,发现已经基本上没有Inflater这个对象了。于是就怀疑GC的时候,没有调用finalize。带着这样的怀疑,笔者把Inflater进行包装在Spring Boot Loader里面替换成自己包装的Inflater,在finalize进行打点监控,结果finalize方法确实被调用了。于是笔者又去看了Inflater对应的C代码,发现初始化的使用了malloc申请内存,end的时候也调用了free去释放内存。

    此刻,笔者只能怀疑free的时候没有真正释放内存,便把Spring Boot包装的InflaterInputStream替换成Java JDK自带的,发现替换之后,内存问题也得以解决了。

    这时,再返过来看gperftools的内存分布情况,发现使用Spring Boot时,内存使用一直在增加,突然某个点内存使用下降了好多(使用量直接由3G降为700M左右)。这个点应该就是GC引起的,内存应该释放了,但是在操作系统层面并没有看到内存变化,那是不是没有释放到操作系统,被内存分配器持有了呢?
    3. æµç¨å¾

     

     

    整个内存分配的流程如上图所示。MCC扫包的默认配置是扫描所有的JAR包。在扫描包的时候,Spring Boot不会主动去释放堆外内存,导致在扫描阶段,堆外内存占用量一直持续飙升。当发生GC的时候,Spring Boot依赖于finalize机制去释放了堆外内存;但是glibc为了性能考虑,并没有真正把内存归返到操作系统,而是留下来放入内存池了,导致应用层以为发生了“内存泄漏”。所以修改MCC的配置路径为特定的JAR包,问题解决。笔者在发表这篇文章时,发现Spring Boot的最新版本(2.0.5.RELEASE)已经做了修改,在ZipInflaterInputStream主动释放了堆外内存不再依赖GC;所以Spring Boot升级到最新版本,这个问题也可以得到解决。

    展开全文
  • 在删除前,通过info memory看下内存情况 Memory used_memory:2205816296 used_memory_human:4.8G used_memory_rss:5579214848 used_memory_rss_human:5.70G ... ... 通过一个小程序,一直删除可...

    现象

    项目中,redis的 key value 量太多,决定对某个db下的key进行删除,也就是Del key。
    在删除前,通过info memory看下内存情况

    Memory
    used_memory:2205816296
    used_memory_human:4.8G
    used_memory_rss:5579214848
    used_memory_rss_human:5.70G
    ...
    ...
    

    通过一个小程序,一直删除可丢弃的key。
    1小时后,过来一看:

    Memory
    used_memory:2205816296
    used_memory_human:2.05G
    used_memory_rss:5579214848
    used_memory_rss_human:5.70G
    ...
    ...
    

    发现redis内部的used_memory使用量已经下降到2.05G了,但是used_memory_rss(redis在系统中进程占用的内存量)并未降低。

    原因

    官方已经说了具体原因
    https://redis.io/topics/memory-optimization
    概括了点内容:

    当键被删除时,Redis并不总是释放(返回)内存到操作系统。这并不是Redis的特别之处,但大多数malloc()实现都是这样工作的。

    例如一个实例有5gb的数据,然后删除相当于2gb的数据,used_memory_rss可能仍会5 gb左右。这是因为底层分配器不能轻松地释放内存。例如,通常将删除的大多数键分配到与其他仍然存在的键相同的页面中。

    然而分配器是聪明和能够重用空闲块的内存,所以在你释放2 gb的5 gb的数据集,当你开始再次增加键,您将看到used_memory_rss保持稳定而不会再增加很多。分配器基本上是尝试重用以前(逻辑上)释放的2GB内存。

    解决方案

    通过原因可以知道,我们其实不用去关注。
    特别是我们定义了maxmemory后,并且定义了maxmemory_policy,那么即使内存满了,redis也会按照淘汰机制方案,清除一些不需要的key,来存放新的key。

    但是如果已经影响到系统内存使用了,也有下面三种方案:

    1. 可以通过 MEMORY PURGE命令进行内存整理。(瞬时,能稍微腾出rss内存空间)
    2. 开启activedefrag,热碎片整理。(会占用CPU,在主线程执行,可以设置CPU占用率)
    3. 重启。
    展开全文
  • linux频繁存取文件内存不释放问题

    千次阅读 2017-08-26 12:57:02
    当你在Linux下频繁存取文件后,物理内存会很快被用光,当程序结束后,内存不会被正常释放,而是一直作为caching.这个问题,貌似有不少人在问,不过都没有看到有什么很好解决的办法.那么我来谈谈这个问题.  先来说说...
  • Python 内存不释放原理

    千次阅读 2016-08-03 09:27:23
    在maillist里面看到无数次的有人问,python速度为...不过今天还是说说,python的内存为什么不释放。 首先,python的初始内存消耗比C大,而且大很多。这个主要来自python解释器的开销,没什么好解释的。用解释器
  • python内存不释放原理

    千次阅读 2015-06-19 16:18:02
    在maillist里面看到无数次的有人问,python...不过今天还是说说,python的内存为什么不释放。 首先,python的初始内存消耗比C大,而且大很多。这个主要来自python解释器的开销,没什么好解释的。用解释器,就得承担
  • 这样编译器在编译阶段就知道该为这个数组分配多少内存了,这就叫静态分配。 那要是这个班的人数是未知的,需要用户手动输入来确定呢? 那就需要动态分配了: void func(int student_count) { int grade[] = ne....
  • 出现以下错误,后来把tomcat的内存增大到1024  严重: Exception initializing page context  java.lang.OutOfMemoryError: Java heap space     在tomcat\bin\catalina.bat的set CURRENT_DIR=%cd% ...
  • MySQL内存不释放

    千次阅读 2014-04-24 17:52:34
    MySQL内存异常占用处理案例一则
  • 1、某分行部署的某台服务器内存占用过高,导致死机; 2、代码层面检查暂未发现问题,服务器硬重启持续一段时间后(3-5天)再次占满。 发现问题: 赶往现场后进行检查,当时是一切正常的,今有DB2进程占用18%,在...
  • Tomcat内存释放不

    千次阅读 2014-07-08 17:30:24
    出现以下错误,后来把tomcat的内存增大到1024 严重: Exception initializing page context java.lang.OutOfMemoryError: Java heap space 在tomcat\bin\catalina.bat的set CURRENT_DIR=%cd% 前面添加 se
  • 出现以下错误,后来把tomcat的内存增大到1024 严重: Exception initializing page context  java.lang.OutOfMemoryError: Java heap space     在tomcat\bin\catalina.bat的set CURRENT_DIR...
  • Python内存管理及释放

    万次阅读 多人点赞 2018-01-23 15:51:43
    python话说会自己管理内存,实际上,对于占用很大内存的对象,并会马上释放。举例,a=range(10000*10000),会发现内存飙升一个多G,del a 或者a=[]都能将内存降下来。。 del 可以删除多个变量,del a,b,c,d ...
  • 在清理前内存使用情况 free -m -m是单位,也可以-g 用以下命令清理内存 echo 1 > /proc/sys/vm/drop_caches 清理后内存使用情况再用以下命令看看。 free –m 多出很多内存了吧。 ...
  • 1.代理声明应为weak,默认strong强引用会导致计数器加1,无法释放内存;应这样声明:@property (nonatomic, weak) SampleClass *sampleClass;2.NSTimer定时器未释放,会导致计数器加1,无法释放内存。 应这样先关闭...
  • 如何手动释放Python的内存

    万次阅读 2019-02-16 11:00:53
    本篇博客将贴一个笔者的实验脚本,用以说明Python确实存在这么一个不释放内存的现象,然后提出一个解决方案,即:先del,再显式调用gc.collect().  脚本和具体效果见下。 实验环境一:Win 7, Python 2.7 ...
  • 我是在arm上运行的,我的测试代码如下: ``` #include #include #include #include using namespace cv; using namespace std;...释放前后,内存并没有太大变化。我感到很困惑,这是什么原因呢?
  • linux tomcat 内存无法释放

    千次阅读 2017-04-18 17:39:17
    出现以下错误,后来把tomcat的内存增大到1024 严重: Exception initializing page context .lang.OutOfMemoryError: Java heap space 在tomcat\bin\catalina.bat的set CURRENT_DIR=%cd% 前面添加  ...
  • openCV内存释放问题

    千次阅读 2016-11-21 11:17:53
    前一天把系统整个重写了一遍,脉络清晰了很多,也终于解决了以前很多崩溃,异常退出的问题。...内存泄露是说没有释放已经能使用的内存,这里一般指堆的内存才需要显示的释放。比如用malloc,calloc,real
  • 随着信息化的推进,系统的依赖性也...发现JVM的内存持续升高,知道内存溢出,一开始我以为是list太大的原因,我将list固定到1w,然后不断循环去数据库取数据,发现问题依旧存在,没有任何改变,所以说明问题的出处,
  • 堆栈内存释放

    千次阅读 2019-05-29 20:12:35
    文章目录js引擎中内存的分类js中堆栈内存的创建和释放内存不销毁的特属情况let和count js引擎中内存的分类 堆内存:堆内存是用来储存数据类型的 栈内存:栈内存提供js代码执行的环境,并储存引用数据类型的数据的 ...
  • linux释放内存的命令

    万次阅读 2019-04-13 02:00:38
    drop_caches的值可以是0-3之间的数字,代表不同的含义:0:不释放(系统默认值)1:释放页缓存2:释放dentries和inodes 3:释放所有缓存释放内存后改回去让系统重新自动分配内存。echo 0 >/proc/sys/vm/drop_...
  • 跨Dll内存分配和释放问题分析

    千次阅读 2019-06-17 23:23:24
    今天遇到一个很奇怪的问题,就是调用内存释放函数时程序崩溃,仔细了解才发现是运行时库链接方式对内存的影响。 现场描述: A.exe使用了B.dll提供的接口,在B.dll中使用malloc申请了一块内存,在B.exe中执行free函数...
  • 动态内存的申请和释放

    千次阅读 2019-01-20 22:15:18
    动态内存的申请和释放 文章目录动态内存的申请和释放1. malloc() 和 free() 的基本概念以及基本用法1.1 函数原型及说明:1.2 被释放的指针1.3 注意事项2. malloc() 到底从哪里得来了内存空间2.1 堆介绍2.2 栈介绍2.3...
  • linux 内存分配释放分析

    千次阅读 2018-02-27 23:33:04
    既然堆内内存brk和sbrk能直接释放,为什么全部使用 mmap 来分配,munmap直接释放呢 ?Linux 的虚拟内存管理有几个关键概念: 1、每个进程都有独立的虚拟地址空间,进程访问的虚拟地址并不是真正的物理地址; ...
  • Linux下释放内存

    万次阅读 2019-04-27 20:39:18
    当在Linux下频繁存取文件后,物理内存会很快被用光,当程序结束后,内存不会被正常释放,而是一直作为caching,因此我们很有必要手动清理系统缓存释放内存。 第一步 我们在清理缓存前应该先执行sync。 因为系统在...
  • Python如何释放内存

    千次阅读 2019-09-23 08:48:09
    一般我会直接用del来删除变量,但是对于占用内存较大的对象,del 并管用,删除了内存也没见减小。有一个解决办法就是调用gc(垃圾回收)模块,就能立刻释放内存。哦,我刚才百度到一个词,叫内存泄漏。 “内存...
  • c++程序崩溃后内存没有释放的问题

    千次阅读 2018-08-10 14:09:16
    如果程序没有通过delete、free语句现实释放内存的话,不论是崩溃(崩溃前为...这是一个致命的bug:加入程序持续运行多次,则可能在后面的某一此中因内存溢出而崩溃,而可能根本找原因(因为前几次都是正确的)。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 311,370
精华内容 124,548
关键字:

内存不释放的原因