转载于:http://blog.csdn.net/hubifeng/article/details/41113789

在处理大型数据过程中,R语言的内存管理就显得十分重要,以下介绍几种常用的处理方法。

1,设置软件的内存

[plain] view
plain
 copy

  1. <span style="font-size:14px;">memory.size(2048) #设置内存大小
  2. memory.size(NA) #查看当前设置下最大内存(?"Memory-limits")
  3. #or memory.limit()
  4. memory.size(F) #查看当前已使用的内存
  5. #or
  6. library(pryr)
  7. mem_used()
  8. mem_change(x <- 1:1e6) #查看执行命令时内存的变化
  9. memory.size(T)  #查看已分配的内存</span>

注意刚开始时已使用内存和已分配内存是同步增加的,但是随着R中的垃圾被清理,已使用内存会减少,而已分配给R的内存一般不会改变。



2,对象的存储

    R中的对象在内存中存于两种不同的地方,一种是堆内存(heap),其基本单元是“Vcells”,每个大小为8字节,新来一个对象就会申请一块空间,把值全部存在这里,和C里面的堆内存很像。第二种是地址对(cons cells),和LISP里的cons cells道理一样,主要用来存储地址信息,最小单元一般在32位系统中是28字节、64位系统中是56字节。

[plain] view
plain
 copy

  1. <span style="font-size:14px;">ls()           #查看当前对象
  2. object.size()    查看对象所占内存
  3. #or
  4. library(pryr)
  5. object_size()  #区别于前者,它进行了换算</span>

1)新建对象分配合适的内存

R会将新的对象存储在“连续”的内存中,如果没有这样的空间就会返回“Cannot allocate vector of size...” 的错误,有以下几种处理方法:

        a) 如果有多个矩阵需要存储,确保优先存储较大的矩阵,然后依次存储较小的矩阵.

        b) 预先分配合适的内存.

            大家都知道R中矩阵的维度并不需要赋一个固定的值(很多语言的数组长度不能为变量),这为写程序带来了极大的方便,因此经常在循环中会出现某个矩阵越来越长的情况,实际上,矩阵每增长一次,即使赋给同名的变量,都需要新开辟一块更大的空间,假设初始矩阵为100K,第二个为101K,一直增到120K,那么,将会分别开辟100K、101K一直到120K的连续堆内存,如果一开始就开一块120K的,使之从101K逐渐增长到120K,将会大大地节约内存。cbind函数也是这个道理,所以在循环中要注意不要滥用。 

        c) 换到64位的计算机,这种问题较少出现.



    2)改变当前对象的存储模式

    例如某个矩阵默认就是"double"的,如果这个矩阵的数值都是整数甚至0-1,完全没必要使用double来占用空间,可以将其改为整数型,可以看到该对象的大小会变为原来的一半。

[plain] view
plain
 copy

  1. <span style="font-size:14px;">storage.mode(x)    #查看对象的存储模式
  2. storage.mode(x) <- "integer"  #整数型存储模式</span>

3)清理中间对象

[plain] view
plain
 copy

  1. <span style="font-size:14px;">rm() #删除变量的引用,经常用它来清理中间对象,其中比较重要的文件可以存在硬盘里,比如csv文件或者RSqlite等
  2. gc() #清理内存空间</span>

4)清理其他对象

.ls.objects() #查看内存消耗较大的文件,并处理掉其他无关对象.代码如下:

[plain] view
plain
 copy

  1. <span style="font-size:14px;">.ls.objects <- function (pos = 1, pattern, order.by = "Size", decreasing=TRUE, head = TRUE, n = 10) {
  2. napply <- function(names, fn) sapply(names, function(x)
  3. fn(get(x, pos = pos)))
  4. names <- ls(pos = pos, pattern = pattern)
  5. obj.class <- napply(names, function(x) as.character(class(x))[1])
  6. obj.mode <- napply(names, mode)
  7. obj.type <- ifelse(is.na(obj.class), obj.mode, obj.class)
  8. obj.size <- napply(names, object.size) / 10^6 # megabytes
  9. obj.dim <- t(napply(names, function(x)
  10. as.numeric(dim(x))[1:2]))
  11. vec <- is.na(obj.dim)[, 1] & (obj.type != "function")
  12. obj.dim[vec, 1] <- napply(names, length)[vec]
  13. out <- data.frame(obj.type, obj.size, obj.dim)
  14. names(out) <- c("Type", "Size", "Rows", "Columns")
  15. out <- out[order(out[[order.by]], decreasing=decreasing), ]
  16. if (head)
  17. out <- head(out, n)
  18. out
  19. }</span>

3,修改存储地址

    这部分可参考文献1。在xp系统上试了一下,得到的存储地址总是不变,不知道xp系统上有没有效...



4,选取数据集的子集

    这是没有办法的办法,迟早要处理全部的数据,不过可以借此调试代码或是建模,如在合适的地方清理中间对象



5,写成脚本文件

    Hadley Wickham 建议写成脚本文件,运行后再清理掉临时文件



6,使用SOAR包

    它可以将特定对象存储为RData文件并无需加载到内存就能进行分析

[plain] view
plain
 copy

  1. <span style="font-size:14px;">r = data.frame(a=rnorm(10,2,.5),b=rnorm(10,3,.5))
  2. library(SOAR)
  3. Sys.setenv(R_LOCAL_CACHE=”testsession”)
  4. ls()
  5. Store(r)
  6. ls()
  7. mean(r[,1])
  8. r$c = rnorm(10,4,.5)
  9. ls()</span>

7,一个有趣的函数

    它会告诉你哪一行的代码消耗了多少时间、内存,释放多少内存,复制了多少向量.

[plain] view
plain
 copy

  1. <span style="font-size:14px;">library(devtools)
  2. devtools::install_github("hadley/lineprof")
  3. library(lineprof)
  4. source("D:/myprojects/project1/read-delim.R")
  5. prof <- lineprof(read_delim("D:/myprojects/project1/diamonds.csv"))
  6. shine(prof)</span>

Reference:

1.点击打开链接

2.点击打开链接

3.点击打开链接

4.点击打开链接





More Reference:

点击打开链接

R语言之内存管理的更多相关文章

  1. JVM内存管理------JAVA语言的内存管理概述

    引言 内存管理一直是JAVA语言自豪与骄傲的资本,它让JAVA程序员基本上可以彻底忽略与内存管理相关的细节,只专注于业务逻辑.不过世界上不存在十全十美的好事,在带来了便利的同时,也因此引入了很多令人抓 ...

  2. C语言的内存管理

    C语言的内存管理 转载:http://blog.csdn.net/wind19/article/details/5964090   对于一个C语言程序而言,内存空间主要由五个部分组成代码段(.text ...

  3. C语言堆内存管理上出现的问题,内存泄露,野指针使用,非法释放指针

    C语言堆内存管理上出现的问题,内存泄露,野指针使用,非法释放指针 (1)开辟的内存没有释放,造成内存泄露 (2)野指针被使用或释放 (3)非法释放指针 (1)开辟的内存没有释放.造成内存泄露,以下的样 ...

  4. JVM内存管理之JAVA语言的内存管理概述

    引言 内存管理一直是JAVA语言自豪与骄傲的资本,它让JAVA程序员基本上可以彻底忽略与内存管理相关的细节,只专注于业务逻辑.不过世界上不存在十全十美的好事,在带来了便利的同时,也因此引入了很多令人抓 ...

  5. c语言之内存管理

    在计算机系统,特别是嵌入式系统中,内存资源是非常有限的.尤其对于移动端开发者来说,硬件资源的限制使得其在程序设计中首要考虑的问题就是如何有效地管理内存资源.本文是作者在学习C语言内存管理的过程中做的一 ...

  6. C语言精华——内存管理,很多学校学习不到的知识~

    在编写程序时,通常并不知道需要处理的数据量,或者难以评估所需处理数据量的变动程度.在这种情况下,要达到有效的资源利用--使用内存管理,必须在运行时动态地分配所需内存,并在使用完毕后尽早释放不需要的内存 ...

  7. C语言回顾-内存管理和指针函数

    1.fgets()函数 该函数是一个文件操作相关的函数 暂时使用这个函数可以从键盘上接收一个字符串,保存到数组中 char str[50]; 1)scanf("%s",str);/ ...

  8. [Objective-C语言教程]内存管理(36)

    内存管理是任何编程语言中最重要的过程之一.它是在需要时分配对象的内存并在不再需要时取消分配的过程. 管理对象内存是一个性能问题; 如果应用程序不释放不需要的对象,则应用程序会因内存占用增加并且性能受损 ...

  9. C语言讲义——内存管理

    动态分配内存 动态分配内存,在堆(heap)中分配. void *malloc(unsigned int num_bytes); 头文件 stdlib.h或malloc.h 向系统申请分配size个字 ...

随机推荐

  1. 单元测试系列:Mock工具Jmockit使用介绍

    更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢! 原文链接:http://www.cnblogs.com/zishi/p/6760272.html Mock工具Jm ...

  2. AdobeFlashBuilder还不如AdobeFlashProfessional写actionscript体验好

    AdobeFlashBuilder还不如AdobeFlashProfessional写actionscript体验好. 这真是奇怪了.

  3. 洛谷 [P4011] 孤岛营救问题

    状压+BFS 通过观察数据范围可知,我们应该状压钥匙种类,直接BFS即可 注意,一个点处可能不知有一把钥匙 #include <iostream> #include <cstdio& ...

  4. BZOJ 4195: [Noi2015]程序自动分析 [并查集 离散化 | 种类并查集WA]

    题意: 给出若干相等和不等关系,判断是否可行 woc NOI考这么傻逼的题飞快打了一个种类并查集交上了然后爆零... 发现相等和不等看错了异或一下再叫woc90分 然后发现md$a \neq b, a ...

  5. POJ1743 Musical Theme [后缀自动机]

    题意:不重叠最长重复子串 后缀数组做法:http://www.cnblogs.com/candy99/p/6227659.html 后缀自动机的话,首先|Right|>=2 然后min(t[u] ...

  6. python dns查询与DNS传输漏洞查询

    前言: 昨天晚上在看DNS协议,然后想到了 DNS传输漏洞.便想写一个DNS查询与DNS传输漏洞查询 DNS传输漏洞介绍: DNS传输漏洞:若DNS服务器配置不当,可能导致匿名用户获取某个域的所有记录 ...

  7. 【学习笔记】Spring中的BeanFactory和ApplicationContext 以及 Bean的生命周期(Y2-3-2)

    BeanFactory和ApplicationContext Spring的IoC容器就是一个实现了BeanFactory接口的可实例化类. Spring提供了两种不同的容器: 一种是最基本的Bean ...

  8. HTML5-svg圆形饼状图进度条实现原理

    <svg width="440" height="440" viewbox="0 0 440 440"> <circle ...

  9. C语言学习之插入排序

    此前的一些博文分别写了C语言中经典的排序方式,选择排序 冒泡排序 桶排序,此文就写 插入排序吧. 相对于冒泡排序,插入排序就比较方便快捷了.和冒泡 选择排序一样,插入排序也需要比较大小.可以这样理解插 ...

  10. hdu3480 Division(dp平行四边形优化)

    题意:将n个数分成m段,每段的代价为最大值减最小值的平方,为代价最小是多少n<=10000 ,m<=5000 题解:先拍好序,从小到大,这样绝对是花费最小的,不过怎么样来做呢?一定很容易想 ...