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 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).
# 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!?