Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

加载大图内存暴增,memory一直增加 #2322

Open
MuRanJiangXia opened this issue Nov 20, 2024 · 7 comments
Open

加载大图内存暴增,memory一直增加 #2322

MuRanJiangXia opened this issue Nov 20, 2024 · 7 comments

Comments

@MuRanJiangXia
Copy link

加载尺寸大的图片内存会一直增
"https://file.guangshaxx.com/detail/2f20eae35be594a963624b7849b8e8eb.jpeg";

图片1.7m,4608 × 3456

用collectionview 复用 30多个cell 加载真机上会超过1gb然后,内存警告 crash,
尝试用
self.kf.setImage(with: url,
placeholder: placeholderImage,
options: options ?? [
.transition(.fade(0.2)),
.cacheOriginalImage,
.processor(DownsamplingImageProcessor(size: CGSize(width: 336, height: 300)))
])
.processor(DownsamplingImageProcessor(size: CGSize(width: 336, height: 300)))
可以降低内存 ,但是memory还是一直增加

设置
// 配置缓存的大小
let memoryCacheSize: Int = 50 * 1024 * 1024 // 50 MB
let diskCacheSize: UInt = 200 * 1024 * 1024 // 200 MB

    // 创建缓存配置
    let cache = KingfisherManager.shared.cache
    
    cache.memoryStorage.config.totalCostLimit = memoryCacheSize
    cache.memoryStorage.config.countLimit = 10
    cache.diskStorage.config.sizeLimit = diskCacheSize

无效~

手动清理
ImageCache.default.clearMemoryCache()
也无效

@make1a
Copy link

make1a commented Dec 9, 2024

看了源码 DownsamplingImageProcessor 中的下采样中的 ImageIO 是读取图片到内存再做的下采样, 作者大大这里能不能优化成 使用 url->下采样的方案。 像这样:
image

@MuRanJiangXia
Copy link
Author

咱们可以处理一些么 减缓 加载大尺寸图片 内存过高这个问题,我这详情还是要加载原尺寸图片的呢

@onevcat
Copy link
Owner

onevcat commented Dec 11, 2024

@make1a 确实这个方式可以缓解 session 那边的压力。但直接使用 CGImageSourceCreateWithURL 的话将完全跳过 Kingfisher 的 download 环节,对现有的结构影响比较大,也会破坏一些已有的 option (比如 downsampling 的同时缓存高清图数据等)。

所以可能需要思考一下怎么才能比较优雅地处理。也许可以用一个 provider 来解决..我试试看。

@onevcat
Copy link
Owner

onevcat commented Dec 11, 2024

@make1a

I tried to implement a provider based solution with the URL image source. It is now in this branch (feature/thumbnail-provider) and you can have a try to see if it can help to improve the usage. (If it helps, I can schedule a release for it)

Some code snippet to use it:

let p = ThumbnailImageDataProvider(url: url, maxPixelSize: 100)
imageView.kf.setImage(with: .provider(p))

@make1a
Copy link

make1a commented Dec 16, 2024

    @objc
    /// 加载本地的图片
    /// - Parameter path: 本地路径
    public func oc_kfSetImage(path: String?, placeholderImage: UIImage?, size: CGSize, complete: ((UIImage?) -> Void)?) {
        guard let path = path else { return  }
        let url = URL(fileURLWithPath: path)
        
        let provider = LocalFileImageDataProvider(fileURL: url)
        
        var options: KingfisherOptionsInfo = [
            .scaleFactor(UIScreen.main.scale),
            .cacheOriginalImage
        ]
        // 获取合适大小的图片展示
        if !url.absoluteString.contains("gif"), size != CGSize.zero {
            options += [.processor(DownsamplingImageProcessor(size: size))]
        }
        
        kf.setImage(with: provider, placeholder: placeholderImage, options: options){ result in
            switch result {
            case .success(let value):
                complete?(value.image)
                
            case .failure(_):
                complete?(nil)
            }
        }
    }

@onevcat In this situation, it seems that the ThumbnailImageDataProvider cannot be used.

@make1a
Copy link

make1a commented Dec 16, 2024

@onevcat I encountered a problem as well, the webp images cannot be displayed, and the system provided the following error log:

findWriterForTypeAndAlternateType:132: *** ERROR: unsupported output file format 'org.webmproject.webp'
CGImageDestinationCreateWithData:4920: *** ERROR: CGImageDestinationCreateWithData: failed to create 'CGImageDestinationRef'
findWriterForTypeAndAlternateType:132: *** ERROR: unsupported output file format 'org.webmproject.webp'
CGImageDestinationCreateWithData:4920: *** ERROR: CGImageDestinationCreateWithData: failed to create 'CGImageDestinationRef'

@SwiftUIBarcode
Copy link

SwiftUIBarcode commented Dec 21, 2024

@onevcat I think I have a similar issue here I'm not sure if its a memory leak though. I have a social media app and the memory cache is getting too large. I have multiple scrollviews with KFimage and I am downsampling the image as well
Here is a small example of a basic cell. Caching the original image does not change the outcome either.

           NavigationLink(value: Route.feedcell(id, user)) {
               KFImage(URL(string: imageUrl))
                   .onSuccess({ _ in
                       onImageLoad()
                   })
                   .placeholder { ProgressView() }
                   .setProcessor(DownsamplingImageProcessor(size: CGSize(width: imageDimension, height: imageDimension)))
                   .scaleFactor(Utilities.screenScale)
                   .resizable()
                   .scaledToFill()
                   .frame(width: imageDimension, height: imageDimension)
                   .clipped()
           }
       } 

The image downsamplingprocessor seems to make the memory go down a bit but it will continue to go higher and higher the more images I load even if I delay it with the downsamplingimageprocessor.
Ive tried to add the following :

  cache.memoryStorage.config.totalCostLimit = 300 * 1024 * 1024
  cache.memoryStorage.config.countLimit = 150
  cache.diskStorage.config.sizeLimit = 1000 * 1024 * 1024

and none of this actually stops the amount of data in the cache it will go to around 3gb and crash also just like in this post
ImageCache.default.clearMemoryCache()
doesnt do anything
So what I am asking pretty much on my social media app how exactly can I show lots of images with kfimage profile pics, feed photos etc without the memory crash happening it seems like the cache will just grow until crash and never clears it self. I had also experimented with cache.memoryStorage.config.expiration = .seconds(10 ) and cache.memoryStorage.config.cleanInterval = 10 and it just doesnt clean the memory you will get a crash from memory with a few 100 images not even that large.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants