首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >内存分配分析器和稳定增长的持久记忆-麻烦的迹象?

内存分配分析器和稳定增长的持久记忆-麻烦的迹象?
EN

Stack Overflow用户
提问于 2021-04-14 22:14:05
回答 1查看 243关注 0票数 0

我有一个应用程序,我正在开发,利益相关者使用它说,该应用程序变得缓慢,无法使用/没有反应后,一致使用一整天。杀死它然后重新开始会使它运转良好。

我的设备上似乎没有这个问题,但我开始在调试器中查看模拟器/电话中的内存使用情况,并且观察到,如果我采取在屏幕与屏幕之间切换的基本操作,我的内存将稳步增加。这些都是相当复杂的屏幕,但是如果我直接转到'add‘屏幕,然后返回到产品列表屏幕,内存就会跳到30 up。如果我一遍又一遍地做同样的动作,我就能把它变成1.1gb的内存。

然后,我更进一步,接通了我的手机,运行了分析器(特别是内存泄漏)。我发现了一个涉及我使用广告的漏洞,所以我只是注释掉了测试的所有代码,当漏洞消失时,内存继续稳步上升。

然后,我运行了这个分配工具,在以相同的方式来回重复了几分钟之后,下面是输出:

正如您所看到的,它是1.53GB,如果我继续执行相同的操作,我可以将其发送到2GB+。奇怪的是,我的手机似乎从来不介意,屏幕只是稍微滞后,否则有时不太坏。当然是有用的。

在我开始拆掉地板之前,我想确认这可能是一个问题的迹象。对我可以从哪里开始找有什么建议?如果持久化内存是问题所在,那么什么是典型的问题或陷阱呢?什么是“匿名vm”?

如果你正在阅读这篇文章,非常感谢你,并感谢你的任何指导!

更新/编辑

在这里进行了一些指导之后,我注意到,奇怪的是,在“添加产品”页面上,每次访问它时,内存都会跳转到10 on。在注释掉代码之后,我将其缩小到导致跳转的这一部分(甚至是代码行)。删除此代码将使其保持稳定,而不会增加。

代码语言:javascript
复制
 //Render collection views
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath as IndexPath) 
        
            let member: MemberDto = groupMembers[indexPath.item]
            let contactInitials = cell.viewWithTag(1) as! UILabel
            let contactAvatar = cell.viewWithTag(2) as! UIImageView
            contactAvatar.image = UIImage(named: "anonymous")
            contactInitials.text = member.displayName
            contactAvatar.layer.cornerRadius = contactAvatar.frame.size.width / 2
            contactAvatar.clipsToBounds = true
            contactAvatar.contentMode = UIViewContentMode.scaleAspectFill
            contactAvatar.layer.borderWidth = 5.0

            
             
            if (member.profileImage.trimmingCharacters(in: CharacterSet.whitespaces) != "") {
                UserService.getProfilePicture(userId: member.userId) {
                    response in
                    
                    contactAvatar.image = response.value
                }
            }

因此,冒犯的代码行在这里:

代码语言:javascript
复制
 contactAvatar.image = response.value

将其添加到这个tableviewcontroller中,并来回执行,会导致内存不断上升和上升,一直到2gb。删除这一行代码(在我设置映像的地方)使其稳定在40-70 to左右,或者上升很慢(几十次重复只达到80 to)。

我意识到我不是在缓存这个图像

我决定尝试用我的框架来缓存它,这立即解决了这个问题。我想这一行代码是把图像拖进内存还是类似的东西?网络调用似乎并不是真正的问题,因为我把它放在其中(甚至对我的API进行了更多的调用),而这似乎并没有通过增加内存来做太多的事情。

只是一些信息:

从主屏幕开始,点击导航菜单栏中的+符号就可以到达这个屏幕。breakpoints

  • Making

  • --在我的故事板上使用一个常规字符,与导航按钮相关联,在这个vc上放置deinit的用户

  • 似乎从未命中过,即使其中包含了打印/代码,并且在我的uitableview控制器中调用的

API似乎不会导致图像加载,除非我将它与设置图像结合起来。如果我打了一个网络电话,但不设置图像,它就不会增加。

我犯了什么错误?我觉得缓存映像就像一条绷带--我记得曾经读过这样的文章:您不应该在UITableViewController中调用图像,但是有什么可供选择的:提前从集合中提取所有用户图像并在桌面视图加载之前缓存它们?

编辑2

就像马特建议的那样,这只是一块绷带。真正的问题仍然存在,因为我知道deinit()没有被调用。在取出大部分代码后,我发现了这个

代码语言:javascript
复制
lblMessage.addTapGestureRecognizer {
            self.txtMessage.becomeFirstResponder()
        }

它映射到扩展类:

代码语言:javascript
复制
public func addTapGestureRecognizer(action: (() -> Void)?) {
        self.isUserInteractionEnabled = true
        self.tapGestureRecognizerAction = action
        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture))
        self.addGestureRecognizer(tapGestureRecognizer)
    }
    public func addLongPressGestureRecognizer(action: (() -> Void)?) {
        self.isUserInteractionEnabled = true
        self.longPressGestureRecognizerAction = action
        let longPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPressGesture))
        self.addGestureRecognizer(longPressGestureRecognizer)
    }
     
    
    // Every time the user taps on the View, this function gets called,
    // which triggers the closure we stored
    @objc fileprivate func handleTapGesture(sender: UITapGestureRecognizer) {
        if let action = self.tapGestureRecognizerAction {
            action?()
        } else {
            print("no action")
        }
    }

所以在这里的某个地方问题就在这里。我要把它带到一个新的线程:Deinit not calling - Cannot find why something is retaining (code provided)

谢谢!希望这能帮上忙。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-04-14 23:37:22

是的,这是个问题,是的,你需要解决它。造成这种情况的两个常见原因是:

  • ,您有一个保留周期,这样至少您的一些视图控制器永远无法退出。

  • --您设计的故事板(或手动控制器)序列不正确,这样(例如)从视图控制器A到查看控制器B,然后为了使您从控制器B“返回”到查看控制器A,您将不再“返回”;相反,您正在将第二个视图控制器A堆在第一个视图控制器A之上,等等。

无论哪种方式,您都可以通过在所有视图控制器中实现deinitprint(self)来快速测试这类事情是否正在进行。然后再玩这个应用程序。如果您没有每次“返回”时在日志中看到打印输出,则会遇到严重的内存问题,因为视图控制器没有在应该释放的时候释放,因此需要修复它。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67099763

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档