mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Plug memory leak in register code
The table storing cell dimensions was never freed. The size of this table is directly proportional to the number of cells in the register. So the more transactions/splits in a register, the more memory was leaked - each time a register was opened and closed. With my huge test book I saw leaks of 4Mb-10Mb per page that was opened/closed.
This commit is contained in:
parent
4cc61463ab
commit
3845611f30
@ -159,7 +159,6 @@ void gnc_split_reg_sort_action_cb (GtkWidget *w, gpointer data);
|
||||
void gnc_split_reg_sort_notes_cb (GtkWidget *w, gpointer data);
|
||||
|
||||
|
||||
void gnc_split_reg_destroy_cb(GtkWidget *widget, gpointer data);
|
||||
void gnc_split_reg_size_allocate( GtkWidget *widget,
|
||||
GtkAllocation *allocation,
|
||||
gpointer user_data );
|
||||
@ -168,6 +167,7 @@ void gnc_split_reg_size_allocate( GtkWidget *widget,
|
||||
static void gnc_split_reg_class_init( GNCSplitRegClass *klass );
|
||||
static void gnc_split_reg_init( GNCSplitReg *gsr );
|
||||
static void gnc_split_reg_init2( GNCSplitReg *gsr );
|
||||
void gnc_split_reg_dispose(GObject *obj);
|
||||
|
||||
FROM_STRING_FUNC(SortType, ENUM_LIST_SORTTYPE)
|
||||
AS_STRING_FUNC(SortType, ENUM_LIST_SORTTYPE)
|
||||
@ -314,6 +314,8 @@ gnc_split_reg_class_init( GNCSplitRegClass *klass )
|
||||
klass->help_changed_cb = NULL;
|
||||
klass->show_popup_menu_cb = NULL;
|
||||
klass->include_date_cb = NULL;
|
||||
|
||||
object_class->dispose = gnc_split_reg_dispose;
|
||||
}
|
||||
|
||||
GtkWidget*
|
||||
@ -354,9 +356,6 @@ gnc_split_reg_init( GNCSplitReg *gsr )
|
||||
gsr->height = -1;
|
||||
gsr->numRows = 10;
|
||||
gsr->read_only = FALSE;
|
||||
|
||||
g_signal_connect( gsr, "destroy",
|
||||
G_CALLBACK (gnc_split_reg_destroy_cb), gsr );
|
||||
}
|
||||
|
||||
static void
|
||||
@ -444,12 +443,18 @@ gsr_setup_status_widgets( GNCSplitReg *gsr )
|
||||
}
|
||||
|
||||
void
|
||||
gnc_split_reg_destroy_cb(GtkWidget *widget, gpointer data)
|
||||
gnc_split_reg_dispose(GObject *obj)
|
||||
{
|
||||
GNCSplitReg *gsr = data;
|
||||
GNCSplitReg *gsr = GNC_SPLIT_REG(obj);
|
||||
|
||||
if (gsr->filter_text)
|
||||
g_free (gsr->filter_text);
|
||||
gsr->filter_text = NULL;
|
||||
|
||||
if (gsr->reg)
|
||||
g_signal_handlers_disconnect_by_data (gsr->reg, gsr);
|
||||
gtk_widget_destroy (GTK_WIDGET (gsr->reg));
|
||||
gsr->reg = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -710,7 +715,9 @@ gnc_split_reg_ld_destroy( GNCLedgerDisplay *ledger )
|
||||
}
|
||||
g_free (state_section);
|
||||
g_free (acct_fullname);
|
||||
|
||||
gnc_ledger_display_set_user_data (ledger, NULL);
|
||||
g_object_unref (gsr);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -763,6 +763,7 @@ gnucash_sheet_finalize (GObject *object)
|
||||
|
||||
sheet = GNUCASH_SHEET (object);
|
||||
|
||||
g_table_resize (sheet->blocks, 0, 0);
|
||||
g_table_destroy (sheet->blocks);
|
||||
sheet->blocks = NULL;
|
||||
|
||||
@ -2214,7 +2215,7 @@ gnucash_sheet_block_set_from_table (GnucashSheet *sheet,
|
||||
|
||||
if (block->style && (block->style != style))
|
||||
{
|
||||
gnucash_style_unref (block->style);
|
||||
gnucash_sheet_style_unref (sheet, block->style);
|
||||
block->style = NULL;
|
||||
}
|
||||
|
||||
@ -2223,7 +2224,7 @@ gnucash_sheet_block_set_from_table (GnucashSheet *sheet,
|
||||
if (block->style == NULL)
|
||||
{
|
||||
block->style = style;
|
||||
gnucash_style_ref(block->style);
|
||||
gnucash_sheet_style_ref(sheet, block->style);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -2323,14 +2324,15 @@ static void
|
||||
gnucash_sheet_block_destroy (gpointer _block, gpointer user_data)
|
||||
{
|
||||
SheetBlock *block = _block;
|
||||
GnucashSheet *sheet = GNUCASH_SHEET(user_data);
|
||||
|
||||
if (block == NULL)
|
||||
return;
|
||||
|
||||
if (block->style)
|
||||
{
|
||||
gnucash_style_unref (block->style);
|
||||
block->style = NULL;
|
||||
gnucash_sheet_style_unref (sheet, block->style);
|
||||
/* Don't free the block itself here. It's managed by the block table */
|
||||
}
|
||||
}
|
||||
|
||||
@ -2588,7 +2590,7 @@ gnucash_sheet_init (GnucashSheet *sheet)
|
||||
|
||||
sheet->blocks = g_table_new (sizeof (SheetBlock),
|
||||
gnucash_sheet_block_construct,
|
||||
gnucash_sheet_block_destroy, NULL);
|
||||
gnucash_sheet_block_destroy, sheet);
|
||||
|
||||
gtk_widget_add_events(GTK_WIDGET(sheet), (GDK_EXPOSURE_MASK
|
||||
| GDK_BUTTON_PRESS_MASK
|
||||
@ -2723,7 +2725,7 @@ gnucash_sheet_new (Table *table)
|
||||
/* some register data */
|
||||
sheet->dimensions_hash_table = g_hash_table_new_full (g_int_hash,
|
||||
g_int_equal,
|
||||
g_free, NULL);
|
||||
g_free, g_free);
|
||||
|
||||
/* add tooltips to sheet */
|
||||
gtk_widget_set_has_tooltip (GTK_WIDGET(sheet), TRUE);
|
||||
|
@ -99,10 +99,15 @@ style_dimensions_destroy (BlockDimensions *dimensions)
|
||||
if (dimensions == NULL)
|
||||
return;
|
||||
|
||||
g_table_destroy (dimensions->cell_dimensions);
|
||||
dimensions->cell_dimensions = NULL;
|
||||
dimensions->refcount--;
|
||||
|
||||
g_free(dimensions);
|
||||
if (dimensions->refcount == 0)
|
||||
{
|
||||
g_table_destroy (dimensions->cell_dimensions);
|
||||
dimensions->cell_dimensions = NULL;
|
||||
|
||||
g_free(dimensions);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -644,7 +649,7 @@ destroy_style_helper (gpointer key, gpointer value, gpointer user_data)
|
||||
SheetBlockStyle *style = value;
|
||||
GnucashSheet *sheet = user_data;
|
||||
|
||||
gnucash_sheet_style_destroy (sheet, style);
|
||||
gnucash_sheet_style_unref (sheet, style);
|
||||
g_free (cursor_name);
|
||||
}
|
||||
|
||||
@ -674,10 +679,12 @@ gnucash_sheet_create_styles (GnucashSheet *sheet)
|
||||
for (node = cursors; node; node = node->next)
|
||||
{
|
||||
CellBlock *cursor = node->data;
|
||||
SheetBlockStyle *style = gnucash_sheet_style_new (sheet, cursor);
|
||||
|
||||
gnucash_sheet_style_ref (sheet, style);
|
||||
g_hash_table_insert (sheet->cursor_styles,
|
||||
g_strdup (cursor->cursor_name),
|
||||
gnucash_sheet_style_new (sheet, cursor));
|
||||
style);
|
||||
}
|
||||
}
|
||||
|
||||
@ -798,7 +805,7 @@ gnucash_sheet_get_style_from_cursor (GnucashSheet *sheet,
|
||||
*/
|
||||
|
||||
void
|
||||
gnucash_style_ref (SheetBlockStyle *style)
|
||||
gnucash_sheet_style_ref (GnucashSheet *sheet, SheetBlockStyle *style)
|
||||
{
|
||||
g_return_if_fail (style != NULL);
|
||||
|
||||
@ -807,14 +814,14 @@ gnucash_style_ref (SheetBlockStyle *style)
|
||||
|
||||
|
||||
void
|
||||
gnucash_style_unref (SheetBlockStyle *style)
|
||||
gnucash_sheet_style_unref (GnucashSheet *sheet, SheetBlockStyle *style)
|
||||
{
|
||||
g_return_if_fail (style != NULL);
|
||||
|
||||
style->refcount--;
|
||||
|
||||
if (style->refcount < 0)
|
||||
g_warning ("Unbalanced Style ref/unref");
|
||||
if (style->refcount == 0)
|
||||
gnucash_sheet_style_destroy (sheet, style);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
|
@ -109,8 +109,8 @@ void gnucash_sheet_style_get_cell_pixel_rel_coords (SheetBlockStyle *style,
|
||||
gint *x, gint *y,
|
||||
gint *w, gint *h);
|
||||
|
||||
void gnucash_style_ref (SheetBlockStyle *style);
|
||||
void gnucash_style_unref (SheetBlockStyle *style);
|
||||
void gnucash_sheet_style_ref (GnucashSheet *sheet, SheetBlockStyle *style);
|
||||
void gnucash_sheet_style_unref (GnucashSheet *sheet, SheetBlockStyle *style);
|
||||
|
||||
void gnucash_sheet_get_borders (GnucashSheet *sheet, VirtualLocation virt_loc,
|
||||
PhysicalCellBorders *borders);
|
||||
|
Loading…
Reference in New Issue
Block a user