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

OutOfMemory error + memory leak #670

Closed
tbenst opened this issue Oct 13, 2017 · 15 comments
Closed

OutOfMemory error + memory leak #670

tbenst opened this issue Oct 13, 2017 · 15 comments

Comments

@tbenst
Copy link

tbenst commented Oct 13, 2017

I'm having an issue that is related to #89. When loading a 1.3GB .tif file that contains a sequence of images, Julia eats up all available memory--21 GB of RAM--before I see LoadError: OutOfMemoryError. In order to free up the memory, I have to end the julia process. The same .tif file opens fine in python using imageio.

Let me know how I can be helpful in troubleshooting?

@timholy
Copy link
Member

timholy commented Oct 13, 2017

Wow, that's a lot of memory. What's your platform? I assume it's using ImageMagick?

Other than recommending that you perhaps try OMETIFF.jl (and use OMETIFF.load to load the file), I'm not sure what to suggest. If you can post the file somewhere I can take a look.

@tbenst
Copy link
Author

tbenst commented Oct 13, 2017

Yes, looks like it's using ImageMagick. I'm on Ubuntu 16.04 (4.4.0-96-generic). Here's the problematic file.

I figured out how to generate files that cause the memory leak. I have a .lif file that I open in Fiji (ImageJ). If I save as a .tif file I can load with Julia, but if I use 'stacks -> Z project' before saving the .tif file, then there is a memory leak in Julia. It could be that the problem is with Fiji, although I can open this file fine in Python.

Edit: I spoke to soon. When directly saved as a .tif, there is no memory blow-up, but load only ingests the first of 7038 images

@tbenst
Copy link
Author

tbenst commented Oct 16, 2017

I made a minimal example to illustrate the problem using a smaller file (222 MB): julia_memory_blowup.tif

using Images
dataFile = "julia_memory_blowup.tif"

tifs = load(dataFile)
println("tifs uses ", sizeof(tifs)/1024^2, " MB")

tifs uses 222.0 MB

However, system monitor shows that Julia is actually using 2.8 GB. I then tried using whos, but the output did not reveal where the problem is:


                          Atom  23412 KB     Module
                AxisAlgorithms     47 KB     Module
                    AxisArrays    194 KB     Module
                          Base               Module
                       BinDeps    194 KB     Module
                         Blink  23330 KB     Module
                      Calculus  23356 KB     Module
                    CatIndices  23225 KB     Module
                     CodeTools  24988 KB     Module
                        Codecs     19 KB     Module
                    ColorTypes  23532 KB     Module
              ColorVectorSpace  23248 KB     Module
                        Colors    370 KB     Module
                        Compat  23283 KB     Module
        ComputationalResources     23 KB     Module
     CoordinateTransformations     78 KB     Module
                          Core               Module
              CustomUnitRanges   1130 bytes  Module
                DataStructures  23440 KB     Module
                     Distances    143 KB     Module
                     DocSeeker  23304 KB     Module
                   DualNumbers  23261 KB     Module
                         EzXML  23444 KB     Module
                      FFTViews   9973 bytes  Module
                        FileIO  23405 KB     Module
             FixedPointNumbers  23793 KB     Module
                      Graphics     73 KB     Module
                        Hiccup  23313 KB     Module
                    HttpCommon     18 KB     Module
                    HttpParser  23273 KB     Module
                    HttpServer    167 KB     Module
                IdentityRanges   3706 bytes  Module
                     ImageAxes     57 KB     Module
                     ImageCore  23508 KB     Module
                ImageFiltering  23658 KB     Module
                   ImageMagick  23351 KB     Module
                 ImageMetadata     33 KB     Module
               ImageMorphology     32 KB     Module
          ImageTransformations    104 KB     Module
                        Images  23733 KB     Module
                IndirectArrays   2828 bytes  Module
                Interpolations    285 KB     Module
                  IntervalSets  23268 KB     Module
                     IterTools     55 KB     Module
                          JSON  23351 KB     Module
                          Juno  23361 KB     Module
                           LNR  23269 KB     Module
                          Lazy  23401 KB     Module
                    MacroTools  23716 KB     Module
                          Main               Module
                  MappedArrays     10 KB     Module
                       MbedTLS  23376 KB     Module
                         Media  23331 KB     Module
                      Mustache     63 KB     Module
                           Mux  23346 KB     Module
                       NaNMath     57 KB     Module
                       OMETIFF     35 KB     Module
                  OffsetArrays     24 KB     Module
                   PaddedViews     17 KB     Module
                   RangeArrays   7699 bytes  Module
                        Ratios   1169 bytes  Module
                      Reexport   4659 bytes  Module
                      Requires  23287 KB     Module
                     Rotations     72 KB     Module
                           SHA     62 KB     Module
          ShowItLikeYouBuildIt     25 KB     Module
                  SimpleTraits     68 KB     Module
              SpecialFunctions  23398 KB     Module
                  StaticArrays  23837 KB     Module
                     StatsBase    660 KB     Module
               StringDistances     22 KB     Module
                TiledIteration     13 KB     Module
                      Tokenize  23403 KB     Module
                     URIParser  23291 KB     Module
                       Unitful  23709 KB     Module
                    WebSockets     44 KB     Module
              WoodburyMatrices     20 KB     Module
                           ans      8 bytes  Float64
                       dataDir     45 bytes  String
                      dataFile     62 bytes  String
                          tifs 227328 KB     512×512×888 Array{Gray{N0f8},3}

@timholy
Copy link
Member

timholy commented Nov 2, 2017

Sorry for the delay here, I had a grant deadline.

The problem seems to be the ImageMagick C library:

julia> using ImageMagick

julia> dataFile = "julia_memory_blowup.tif"
"julia_memory_blowup.tif"

julia> wand = ImageMagick.MagickWand()
ImageMagick.MagickWand(Ptr{Void} @0x0000000003b80210)

julia> ccall(ImageMagick.MagickReadImage[], Cint, (Ptr{Void}, Ptr{UInt8}), wand, dataFile)
1

For me this is enough to exhibit the 2GB of RAM usage. Since this is a single ccall it pretty clearly localizes the problem to something we can't control from Julia.

Not sure what to do. One option would be to write a pure-Julia TIFF reader. Three repositories that might be relevant:

One can easily explore OMETIFF, even though it's not the default loader for "plain" tiff:

julia> using FileIO

julia> dataFile = "julia_memory_blowup.tif"
"julia_memory_blowup.tif"

julia> img2 = load(File(format"OMETIFF", dataFile));
INFO: Recompiling stale cache file /home/tim/.julia/lib/v0.6/OMETIFF.ji for module OMETIFF.
Error encountered while loading "julia_memory_blowup.tif".
Fatal error:
ERROR: MethodError: Cannot `convert` an object of type String to an object of type FileIO.LoaderError
This may have arisen from a call to the constructor FileIO.LoaderError(...),
since type constructors fall back to convert methods.

The error message suggests some (small) mistake in OMETIFF, but the bigger picture may be that the format may not be compatible. CC @tlnagy.

@tlnagy
Copy link
Contributor

tlnagy commented Nov 2, 2017

Ooof. I'm not surprised that OMETIFF.jl breaks because I assumed (ugh, i know) that it would only be invoked for proper OME-TIFF files. The only difference between TIFF and OME-TIFF files is the presence of an extra tag containing all the OME-XML metadata so it should be possible to have OMETIFF.jl degrade gracefully. I'll see if it's a simple fix.

@tlnagy
Copy link
Contributor

tlnagy commented Nov 2, 2017

Hah. So that error is OMETIFF.jl trying to throw an error that the file provided doesn't have a filename ending in .ome.tif. 🤦‍♂️

That's what I get for ignoring a gap in coverage of my tests.

@c42f
Copy link
Member

c42f commented Nov 2, 2017

@timholy The status of OpenImageIO.jl is that it works for some simple cases but development is on hold for the moment - right now I'm trying to put what time I have into Base to make 1.0 as good as it can be :-)

@johnnychen94
Copy link
Member

johnnychen94 commented Apr 2, 2019

we might need to close this issue since it's already fixed

@tbenst
Copy link
Author

tbenst commented Apr 11, 2019

@johnnychen94 just tested and julia_memory_blowup.tif still consumes > 2GB of memory

@johnnychen94
Copy link
Member

It runs well in my machine:

Ubuntu 16.04:

julia> using Images

julia> @time tifs = load("julia_memory_blowup.tif");
 13.358631 seconds (21.26 M allocations: 1.651 GiB, 5.86% gc time)

julia> println("tifs uses ", sizeof(tifs)/1024^2, " MB")
tifs uses 222.0 MB
version
julia> versioninfo()
Julia Version 1.1.0
Commit 80516ca202 (2019-01-21 21:24 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Xeon(R) CPU E5-2678 v3 @ 2.50GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-6.0.1 (ORCJIT, haswell)
(v1.1) pkg> st
    Status `~/.julia/environments/v1.1/Project.toml`
  [fbb218c0] BSON v0.2.2
  [6e4b80f9] BenchmarkTools v0.4.2
  [159f3aea] Cairo v0.5.6
  [3da002f7] ColorTypes v0.7.5
  [c3611d14] ColorVectorSpace v0.6.2
  [5ae59095] Colors v0.9.5
  [a81c6b42] Compose v0.7.3
  [3a865a2d] CuArrays v1.0.1
  [31a5f54b] Debugger v0.3.0
  [35a29f4d] DocumenterTools v0.1.0
  [587475ba] Flux v0.8.1
  [186bb1d3] Fontconfig v0.2.0
  [0c68f7d7] GPUArrays v0.6.1
  [a2cc645c] GraphPlot v0.3.1
  [4c0ca9eb] Gtk v0.16.5
  [2c695a8d] HistogramThresholding v0.2.1
  [7073ff75] IJulia v1.18.0
  [f332f351] ImageContrastAdjustment v0.1.1
  [a09fc81d] ImageCore v0.7.4
  [6218d12a] ImageMagick v0.7.1
  [86fae568] ImageView v0.8.2
  [916415d5] Images v0.17.3
  [093fc24a] LightGraphs v1.2.0
  [f27b6e38] Polynomials v0.5.2
  [438e738f] PyCall v1.91.1
  [d330b81b] PyPlot v2.8.0
  [fd094767] Suppressor v0.1.1
  [5e47fb64] TestImages v0.4.1
  [b4f28e30] TikzGraphs v1.0.1
  [37f6aa50] TikzPictures v3.0.5
  [10745b16] Statistics 

Some related issues are fixed by #746:

@timholy
Copy link
Member

timholy commented Apr 11, 2019

I don't think it has anything to do with show methods since I was able to replicate it in the REPL with no display. But @johnnychen94 is still mostly right, in that this doesn't appear to be a problem on the Julia side. The only thing we could likely do is develop a completely different image loading library. Since we're all volunteers here...contributions would be welcome! 😄

However, @tbenst it might be worth trying to ccall malloc_trim as described in JuliaLang/julia#30653. Let us know if that solves the problem.

@johnnychen94
Copy link
Member

Sorry I misunderstood the issue problem here. I thought it's related to sizeof(tifs), and yes I do spotted a >2GB memory usage.

@tbenst
Copy link
Author

tbenst commented Apr 11, 2019

@timholy I certainly appreciate all the amazing work you do on Julia in addition to being a neuroscientist! 😃 Thanks to that thread, I just found that calling GC.gc() after the load releases the extra memory. Perhaps adding this after ccall may help mitigate the issue? I'm guessing that malloc_trim will also solve the issue

@johnnychen94
Copy link
Member

An update on this:

With Julia 1.6.0 and ImageIO, which uses TIFFImages made by @tlnagy, loading the 222MB file now takes 500MB memory on macOS and 400MB on Ubuntu so definitely a big improvement.

(@v1.6) pkg> st ImageIO FileIO
      Status `~/.julia/environments/v1.6/Project.toml`
  [5789e2e9] FileIO v1.6.5
  [82e4d734] ImageIO v0.5.3

@johnnychen94
Copy link
Member

I assume this is good to close.

This issue was closed.
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

5 participants