加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – Ruby net / ldap模块中的内存泄漏

发布时间:2020-12-17 03:34:03 所属栏目:百科 来源:网络整理
导读:作为我的Rails应用程序的一部分,我编写了一个小的导入程序,它从我们的LDAP系统中吸取数据并将其变成User表.不幸的是,与LDAP相关的代码在迭代我们的32K用户时泄漏了大量内存,而我无法弄清楚如何解决这个问题. 这个问题似乎以某种方式与LDAP库有关,因为当我删
作为我的Rails应用程序的一部分,我编写了一个小的导入程序,它从我们的LDAP系统中吸取数据并将其变成User表.不幸的是,与LDAP相关的代码在迭代我们的32K用户时泄漏了大量内存,而我无法弄清楚如何解决这个问题.

这个问题似乎以某种方式与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况很好地稳定了.此外,正在激增的对象是Net :: BER :: BerIdentifiedString和Net :: BER :: BerIdentifiedArray,它们都是LDAP库的一部分.

当我运行导入时,内存使用量最终达到1GB以上.如果存在问题,我需要找到一些方法来纠正我的代码,或者解决问题所在,解决LDAP内存问题. (或者如果有一个更好的LDAP库用于Ruby的大型导入,我也会对此持开放态度.)

这是我的代码的相关部分:

require 'net/ldap'
require 'pp'

class User < ActiveRecord::Base
  validates_presence_of :name,:login,:email

  # This method is resonsible for populating the User table with the
  # login,name,and email of anybody who might be using the system.
  def self.import_all
    # initialization stuff. set bind_dn,bind_pass,ldap_host,base_dn and filter

    ldap = Net::LDAP.new
    ldap.host = ldap_host
    ldap.auth bind_dn,bind_pass
    ldap.bind

    begin
      # Build the list
      records = records_updated = new_records = 0
      ldap.search(:base => base_dn,:filter => filter ) do |entry|
        name = entry.givenName.to_s.strip + " " + entry.sn.to_s.strip
        login = entry.name.to_s.strip
        email = login + "@txstate.edu"
        user = User.find_or_initialize_by_login :name => name,:login => login,:email => email
        if user.name != name
          user.name = name
          user.save
          logger.info( "Updated: " + email )
          records_updated = records_updated + 1
        elsif user.new_record?
          user.save
          new_records = new_records + 1
        else
          # update timestamp so that we can delete old records later
          user.touch
        end
        records = records + 1
      end

      # delete records that haven't been updated for 7 days
      records_deleted = User.destroy_all( ["updated_at < ?",Date.today - 7 ] ).size

      logger.info( "LDAP Import Complete: " + Time.now.to_s )
      logger.info( "Total Records Processed: " + records.to_s )
      logger.info( "New Records: " + new_records.to_s )
      logger.info( "Updated Records: " + records_updated.to_s ) 
      logger.info( "Deleted Records: " + records_deleted.to_s )

    end

  end
end

提前感谢任何帮助/指针!

顺便说一下,我也在net / ldap支持论坛上询问了这个问题,但没有得到任何有用的指示.

解决方法

需要注意的一件非常重要的事情是,您永远不会使用方法调用的结果.这意味着你应该传递:return_result =>假到ldap.search:

ldap.search(:base => base_dn,:filter => filter,:return_result => false ) do |entry|

从文档:“when:return_result => false,#search将仅返回一个布尔值,以指示操作是否成功.这可以提高非常大的结果集的性能,因为库可以在块后丢弃内存中的每个条目处理它.“

换句话说,如果你不使用这个标志,所有条目都将存储在内存中,即使你不需要它们!所以,使用此选项.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读