NSAutoreleasePool


在iOS开发中,苹果不建议使用半自动内存管理方式,但不像GC机制一样被禁用,原因是这种半自动内存管理容易在某些情况下导致内存溢出。我们看如下代码:
   
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
for(int i=0;i<1000000;i++){
    NSString *s = @"......";
    if(i%1000==0){
       //执行代码
    }
}
[pool release];

我们这里在循环100万次的代码,每次都创建一个NSString实例,由于NSString没有使用alloc创建实例,因此我们使用了自动回收池,但这里有问题是,这100万个NSString要在for循环完,pool release方法调用后才回收,这就造成for循环调用过程中,内存占用一直上涨。
当然你可以改进上面的代码如下所示:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
for(int i=0;i<1000000;i++){
    NSString *s = @"......";
    if(i%1000==0){
       [pool release];
       pool = [[NSAutoreleasePool alloc]init];
    }
}
[pool release];  

上面代码每循环1000次,就回收自动回收池,然后再紧接着重新创建一个自动回收池给下1000个NSString对象使用。其实这个问题很像Hiberate的一个问题:给你1000万行记录的Excel,让你导入到数据库,你该怎样做呢?直接做法如下所示:

Session session = 获取Hibernate的JDBC连接对象
for(int i =0;i<Excel的行数;i++){
  Object obj = 每一行Excel记录对应的JAVA对象;
  session.save(obj);
}
Transaction.commit();

由于Hibernate的一级缓存是在你提交事务的时候才清空,并且刷新到数据库上的,因此在循环结束前,你的一级缓存会积累大量obj对象,使得内存专用越来越大。解决方法与Objective-C的自动回收池差不多,就是如下的做法:

Session session = 获取Hibernate的JDBC连接对象
for(int i =0;i<Excel的行数;i++){
  Object obj = 每一行Excel记录对应的JAVA对象;
  session.save(obj);
  for(i%1000==0){
  session.flush();
  }
}
Transaction.commit();

我们看到每隔1000次就刷新一级缓存,它的作用是清理一级缓存,把数据都发送到数据库上面去,但是我并没有提交事务。也就是数据都从JVM转移到数据库的缓冲区积累了,数据库依然会等待循环结束后的commit()操作才会提交事务。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值