Gtk.jl
Gtk.jl copied to clipboard
Unknown memory allocation when displaying pixels on Canvas
Hi all! I have some memory allocation I don’t understand when using Gtk, and hoping for some advice.
I’ve built an application to display and tweak (many) scientifically computed 2kx2k images, and they are displayed through Gtk. In the process of optimizing it (using @time), I’ve notice some memory allocations I can’t understand. Below is a minimum working example. Is this a bug? Is there a way I can avoid these allocations? Perhaps I should I be using something different than a GtkCanvas?
Any comments appreciated. I’m using Julia 1.7.3
Julia Version 1.7.3
Commit 742b9abb4d (2022-05-06 12:58 UTC)
Platform Info:
OS: macOS (x86_64-apple-darwin21.4.0)
CPU: Intel(R) Core(TM) i7-8559U CPU @ 2.70GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-12.0.1 (ORCJIT, skylake)
and Gtk libraries
[4c0ca9eb] Gtk v1.2.1
[27996c0f] GtkReactive v1.0.6
Here is an example that demonstrates the issue (I’m on Mac, but I think it happens on Win as well). When this code is run, the ui opens, and the update is called several times, showing near zero memory allocation. When the "update" button is pushed, there is memory allocation (every time). And, when switching tabs, then clicking update, this memory churn increases. I'm not really sure why, but I would like to eliminate it, or have a better, more efficient design.
# gtk_test.jl
#
# demonstrate unwanted memory allocation from displaying images
# on startup, no memory allocations
# on clicking Update, memory allocated every time
# more memory allocated once different tabs exposed
#
import Gtk
import GtkReactive
CANVAS_SIZE_PIXELS = 512
IMAGES_SIZE_PIXELS = 2048
function GtkFigure(width, height)
c = Gtk.GtkCanvas()
Gtk.set_gtk_property!(c, :width_request, width)
Gtk.set_gtk_property!(c, :height_request, height)
c
end
grid_win = Gtk.GtkGrid()
canvas_img_01 = GtkFigure(CANVAS_SIZE_PIXELS, CANVAS_SIZE_PIXELS)
canvas_img_02 = GtkFigure(CANVAS_SIZE_PIXELS, CANVAS_SIZE_PIXELS)
canvas_img_03 = GtkFigure(CANVAS_SIZE_PIXELS, CANVAS_SIZE_PIXELS)
canvas_img_04 = GtkFigure(CANVAS_SIZE_PIXELS, CANVAS_SIZE_PIXELS)
canvas_img_05 = GtkFigure(CANVAS_SIZE_PIXELS, CANVAS_SIZE_PIXELS)
# (an intermediate grid seems required to avoid a Gdk assert 2019-09-22 ABahm/TKnopp)
notebk_canvases = Gtk.GtkNotebook()
push!(notebk_canvases, canvas_img_01, "01")
push!(notebk_canvases, canvas_img_02, "02")
push!(notebk_canvases, canvas_img_03, "03")
push!(notebk_canvases, canvas_img_04, "04")
push!(notebk_canvases, canvas_img_05, "05")
button_update = Gtk.GtkButton("Update")
grid_notebook = Gtk.GtkGrid()
grid_notebook[1,1] = notebk_canvases
grid_win[1,1] = button_update
grid_win[1,2] = grid_notebook
# create window
win = Gtk.GtkWindow("memory allocation after clicking tabs")
push!(win, grid_win)
Gtk.showall(win)
function set_figure!(canvas, img)
Gtk.draw(canvas) do widget
copy!(canvas, img)
Gtk.reveal(canvas)
end
end
function button_update_clicked(widget)
r = rand(IMAGES_SIZE_PIXELS,IMAGES_SIZE_PIXELS)
@time begin
set_figure!(canvas_img_01, r)
set_figure!(canvas_img_02, r)
set_figure!(canvas_img_03, r)
set_figure!(canvas_img_04, r)
set_figure!(canvas_img_05, r)
end
end
id = Gtk.signal_connect(button_update_clicked, button_update, "clicked")
# these calls report ~ "0.000004 seconds (5 allocations: 160 bytes)"
button_update_clicked(nothing)
button_update_clicked(nothing)
button_update_clicked(nothing)
button_update_clicked(nothing)
# but clicking the update button, and switching tabs starts to use memory!?