diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index 85335af..2f3d954 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -2117,6 +2117,9 @@ g_string_chunk_free
 GArray
 g_array_new
 g_array_sized_new
+g_array_ref
+g_array_unref
+g_array_get_element_size
 g_array_append_val
 g_array_append_vals
 g_array_prepend_val
@@ -2139,6 +2142,10 @@ g_array_free
 GPtrArray
 g_ptr_array_new
 g_ptr_array_sized_new
+g_ptr_array_new_with_free_func
+g_ptr_array_set_free_func
+g_ptr_array_ref
+g_ptr_array_unref
 g_ptr_array_add
 g_ptr_array_remove
 g_ptr_array_remove_index
@@ -2160,6 +2167,8 @@ g_ptr_array_foreach
 GByteArray
 g_byte_array_new
 g_byte_array_sized_new
+g_byte_array_ref
+g_byte_array_unref
 g_byte_array_append
 g_byte_array_prepend
 g_byte_array_remove_index
diff --git a/docs/reference/glib/tmpl/arrays.sgml b/docs/reference/glib/tmpl/arrays.sgml
index 34c5497..890e15c 100644
--- a/docs/reference/glib/tmpl/arrays.sgml
+++ b/docs/reference/glib/tmpl/arrays.sgml
@@ -69,7 +69,7 @@ added to the #GArray.
 
 <!-- ##### FUNCTION g_array_new ##### -->
 <para>
-Creates a new #GArray.
+Creates a new #GArray with a reference count of 1.
 </para>
 
 @zero_terminated: %TRUE if the array should have an extra element at the end
@@ -83,9 +83,9 @@ when they are allocated.
 <!-- ##### FUNCTION g_array_sized_new ##### -->
 <para>
 Creates a new #GArray with @reserved_size elements
-preallocated. This avoids frequent reallocation, if you are going to
-add many elements to the array. Note however that the size of the
-array is still 0.
+preallocated and a reference count of 1. This avoids frequent reallocation,
+if you are going to add many elements to the array. Note however that the
+size of the array is still 0.
 </para>
 
 @zero_terminated: %TRUE if the array should have an extra element at the end with all bits cleared.
@@ -95,6 +95,32 @@ array is still 0.
 @Returns: the new #GArray.
 
 
+<!-- ##### FUNCTION g_array_ref ##### -->
+<para>
+
+</para>
+
+@array: 
+@Returns: 
+
+
+<!-- ##### FUNCTION g_array_unref ##### -->
+<para>
+
+</para>
+
+@array: 
+
+
+<!-- ##### FUNCTION g_array_get_element_size ##### -->
+<para>
+
+</para>
+
+@array: 
+@Returns: 
+
+
 <!-- ##### MACRO g_array_append_val ##### -->
 <para>
 Adds the value on to the end of the array.
@@ -292,8 +318,11 @@ If the array was created with @clear_ set to %TRUE, the new elements are set to
 <para>
 Frees the memory allocated for the #GArray.
 If @free_segment is %TRUE it frees the memory block holding the elements
-as well. Pass %FALSE if you want to free the #GArray wrapper but preserve
-the underlying array for use elsewhere.
+as well and also each element if @array has a @element_free_func set.
+Pass %FALSE if you want to free the #GArray wrapper but preserve
+the underlying array for use elsewhere. If the reference count of @array
+is greater than one, the #GArray wrapper is preserved but the size of
+@array will be set to zero.
 </para>
 <note>
 <para>
diff --git a/docs/reference/glib/tmpl/arrays_byte.sgml b/docs/reference/glib/tmpl/arrays_byte.sgml
index eb3c400..b1c4e4f 100644
--- a/docs/reference/glib/tmpl/arrays_byte.sgml
+++ b/docs/reference/glib/tmpl/arrays_byte.sgml
@@ -63,7 +63,7 @@ added to the #GByteArray.
 
 <!-- ##### FUNCTION g_byte_array_new ##### -->
 <para>
-Creates a new #GByteArray.
+Creates a new #GByteArray with a reference count of 1.
 </para>
 
 @Returns: the new #GByteArray.
@@ -80,6 +80,23 @@ the array. Note however that the size of the array is still 0.
 @Returns: the new #GByteArray.
 
 
+<!-- ##### FUNCTION g_byte_array_ref ##### -->
+<para>
+
+</para>
+
+@array: 
+@Returns: 
+
+
+<!-- ##### FUNCTION g_byte_array_unref ##### -->
+<para>
+
+</para>
+
+@array: 
+
+
 <!-- ##### FUNCTION g_byte_array_append ##### -->
 <para>
 Adds the given bytes to the end of the #GByteArray.
@@ -181,7 +198,9 @@ Sets the size of the #GByteArray, expanding it if necessary.
 <!-- ##### FUNCTION g_byte_array_free ##### -->
 <para>
 Frees the memory allocated by the #GByteArray.
-If @free_segment is %TRUE it frees the actual byte data.
+If @free_segment is %TRUE it frees the actual byte data. If the reference
+count of @array is greater than one, the #GByteArray wrapper is preserved but
+the size of @array will be set to zero.
 </para>
 
 @array: a #GByteArray.
diff --git a/docs/reference/glib/tmpl/arrays_pointer.sgml b/docs/reference/glib/tmpl/arrays_pointer.sgml
index 15c5792..47802cc 100644
--- a/docs/reference/glib/tmpl/arrays_pointer.sgml
+++ b/docs/reference/glib/tmpl/arrays_pointer.sgml
@@ -73,7 +73,7 @@ Contains the public fields of a pointer array.
 
 <!-- ##### FUNCTION g_ptr_array_new ##### -->
 <para>
-Creates a new #GPtrArray.
+Creates a new #GPtrArray with a reference count of 1.
 </para>
 
 @Returns: the new #GPtrArray.
@@ -82,15 +82,50 @@ Creates a new #GPtrArray.
 <!-- ##### FUNCTION g_ptr_array_sized_new ##### -->
 <para>
 Creates a new #GPtrArray with @reserved_size pointers
-preallocated. This avoids frequent reallocation, if you are going to
-add many pointers to the array. Note however that the size of the
-array is still 0.
+preallocated and a reference count of 1. This avoids frequent reallocation,
+if you are going to add many pointers to the array. Note however that the size
+of the array is still 0.
 </para>
 
 @reserved_size: number of pointers preallocated.
 @Returns: the new #GPtrArray.
 
 
+<!-- ##### FUNCTION g_ptr_array_new_with_free_func ##### -->
+<para>
+
+</para>
+
+@element_free_func: 
+@Returns: 
+
+
+<!-- ##### FUNCTION g_ptr_array_set_free_func ##### -->
+<para>
+
+</para>
+
+@array: 
+@element_free_func: 
+
+
+<!-- ##### FUNCTION g_ptr_array_ref ##### -->
+<para>
+
+</para>
+
+@array: 
+@Returns: 
+
+
+<!-- ##### FUNCTION g_ptr_array_unref ##### -->
+<para>
+
+</para>
+
+@array: 
+
+
 <!-- ##### FUNCTION g_ptr_array_add ##### -->
 <para>
 Adds a pointer to the end of the pointer array.
@@ -228,14 +263,17 @@ Returns the pointer at the given index of the pointer array.
 <!-- ##### FUNCTION g_ptr_array_free ##### -->
 <para>
 Frees the memory allocated for the #GPtrArray.
-If @free_segment is %TRUE it frees the memory block holding the elements
+If @free_seg is %TRUE it frees the memory block holding the elements
 as well. Pass %FALSE if you want to free the #GPtrArray wrapper but preserve
-the underlying array for use elsewhere.
+the underlying array for use elsewhere. If the reference count of @array
+is greater than one, the #GPtrArray wrapper is preserved but the size of
+@array will be set to zero.
 </para>
 <note>
 <para>
-If array contents point to dynamically-allocated memory, they should be freed
-separately.
+If array contents point to dynamically-allocated memory, they should
+be freed separately if @free_seg is %TRUE and no #GDestroyNotify
+function has been set for @array.
 </para>
 </note>
 
diff --git a/glib/garray.c b/glib/garray.c
index b05ded6..ebd230a 100644
--- a/glib/garray.c
+++ b/glib/garray.c
@@ -55,6 +55,7 @@ struct _GRealArray
   guint   elt_size;
   guint   zero_terminated : 1;
   guint   clear : 1;
+  volatile gint ref_count;
 };
 
 #define g_array_elt_len(array,i) ((array)->elt_size * (i))
@@ -91,6 +92,7 @@ GArray* g_array_sized_new (gboolean zero_terminated,
   array->zero_terminated = (zero_terminated ? 1 : 0);
   array->clear           = (clear ? 1 : 0);
   array->elt_size        = elt_size;
+  array->ref_count       = 1;
 
   if (array->zero_terminated || reserved_size != 0)
     {
@@ -101,14 +103,78 @@ GArray* g_array_sized_new (gboolean zero_terminated,
   return (GArray*) array;
 }
 
+/**
+ * g_array_ref:
+ * @array: A #GArray.
+ *
+ * Atomically increments the reference count of @array by one. This
+ * function is MT-safe and may be called from any thread.
+ *
+ * Returns: The passed in #GArray.
+ *
+ * Since: 2.22
+ **/
+GArray *
+g_array_ref (GArray *farray)
+{
+  GRealArray *array = (GRealArray*) farray;
+  g_return_val_if_fail (g_atomic_int_get (&array->ref_count) > 0, farray);
+  g_atomic_int_inc (&array->ref_count);
+  return farray;
+}
+
+/**
+ * g_array_unref:
+ * @array: A #GArray.
+ *
+ * Atomically decrements the reference count of @array by one. If the
+ * reference count drops to 0, all memory allocated by the array is
+ * released. This function is MT-safe and may be called from any
+ * thread.
+ *
+ * Since: 2.22
+ **/
+void
+g_array_unref (GArray *farray)
+{
+  GRealArray *array = (GRealArray*) farray;
+  g_return_if_fail (g_atomic_int_get (&array->ref_count) > 0);
+  if (g_atomic_int_dec_and_test (&array->ref_count))
+    g_array_free (farray, TRUE);
+}
+
+/**
+ * g_array_get_element_size:
+ * @array: A #GArray.
+ *
+ * Gets the size of the elements in @array.
+ *
+ * Returns: Size of each element, in bytes.
+ *
+ * Since: 2.22
+ **/
+guint
+g_array_get_element_size (GArray *farray)
+{
+  GRealArray *array = (GRealArray*) farray;
+  return array->elt_size;
+}
+
 gchar*
-g_array_free (GArray   *array,
+g_array_free (GArray   *farray,
 	      gboolean  free_segment)
 {
+  GRealArray *array = (GRealArray*) farray;
   gchar* segment;
+  gboolean preserve_wrapper;
 
   g_return_val_if_fail (array, NULL);
 
+  /* if others are holding a reference, preserve the wrapper but do free/return the data */
+  preserve_wrapper = FALSE;
+  if (g_atomic_int_get (&array->ref_count) > 1)
+    preserve_wrapper = TRUE;
+
   if (free_segment)
     {
       g_free (array->data);
@@ -117,7 +183,16 @@ g_array_free (GArray   *array,
   else
     segment = array->data;
 
-  g_slice_free1 (sizeof (GRealArray), array);
+  if (preserve_wrapper)
+    {
+      array->data            = NULL;
+      array->len             = 0;
+      array->alloc           = 0;
+    }
+  else
+    {
+      g_slice_free1 (sizeof (GRealArray), array);
+    }
 
   return segment;
 }
@@ -352,9 +427,11 @@ typedef struct _GRealPtrArray  GRealPtrArray;
 
 struct _GRealPtrArray
 {
-  gpointer *pdata;
-  guint     len;
-  guint     alloc;
+  gpointer     *pdata;
+  guint         len;
+  guint         alloc;
+  volatile gint ref_count;
+  GDestroyNotify element_free_func;
 };
 
 static void g_ptr_array_maybe_expand (GRealPtrArray *array,
@@ -374,6 +451,8 @@ g_ptr_array_sized_new (guint reserved_size)
   array->pdata = NULL;
   array->len = 0;
   array->alloc = 0;
+  array->ref_count = 1;
+  array->element_free_func = NULL;
 
   if (reserved_size != 0)
     g_ptr_array_maybe_expand (array, reserved_size);
@@ -381,23 +460,123 @@ g_ptr_array_sized_new (guint reserved_size)
   return (GPtrArray*) array;  
 }
 
+/**
+ * g_ptr_array_new_with_free_func:
+ * @element_free_func: A function to free elements with destroy @array or %NULL.
+ *
+ * Creates a new #GPtrArray with a reference count of 1 and use @element_free_func
+ * for freeing each element when the array is destroyed either via
+ * g_ptr_array_unref() or when g_ptr_array_free() is called with @free_segment
+ * set to %TRUE.
+ *
+ * Returns: A new #GPtrArray.
+ *
+ * Since: 2.22
+ **/
+GPtrArray *
+g_ptr_array_new_with_free_func (GDestroyNotify element_free_func)
+{
+  GPtrArray *array;
+
+  array = g_ptr_array_new ();
+  g_ptr_array_set_free_func (array, element_free_func);
+  return array;
+}
+
+/**
+ * g_ptr_array_set_free_func:
+ * @array: A #GPtrArray.
+ * @element_free_func: A function to free elements with destroy @array or %NULL.
+ *
+ * Sets a function for freeing each element when @array is destroyed
+ * either via g_ptr_array_unref() or when g_ptr_array_free() is called
+ * with @free_segment set to %TRUE.
+ *
+ * Since: 2.22
+ **/
+void
+g_ptr_array_set_free_func (GPtrArray        *farray,
+                           GDestroyNotify    element_free_func)
+{
+  GRealPtrArray* array = (GRealPtrArray*) farray;
+  array->element_free_func = element_free_func;
+}
+
+/**
+ * g_ptr_array_ref:
+ * @array: A #GArray.
+ *
+ * Atomically increments the reference count of @array by one. This
+ * function is MT-safe and may be called from any thread.
+ *
+ * Returns: The passed in #GPtrArray.
+ *
+ * Since: 2.22
+ **/
+GPtrArray *
+g_ptr_array_ref (GPtrArray *farray)
+{
+  GRealPtrArray *array = (GRealPtrArray*) farray;
+  g_return_val_if_fail (g_atomic_int_get (&array->ref_count) > 0, farray);
+  g_atomic_int_inc (&array->ref_count);
+  return farray;
+}
+
+/**
+ * g_ptr_array_unref:
+ * @array: A #GPtrArray.
+ *
+ * Atomically decrements the reference count of @array by one. If the
+ * reference count drops to 0, the effect is the same as calling
+ * g_ptr_array_free() with @free_segment set to %TRUE. This function
+ * is MT-safe and may be called from any thread.
+ *
+ * Since: 2.22
+ **/
+void
+g_ptr_array_unref (GPtrArray *farray)
+{
+  GRealPtrArray *array = (GRealPtrArray*) farray;
+  g_return_if_fail (g_atomic_int_get (&array->ref_count) > 0);
+  if (g_atomic_int_dec_and_test (&array->ref_count))
+    g_ptr_array_free (farray, TRUE);
+}
+
 gpointer*
-g_ptr_array_free (GPtrArray *array,
+g_ptr_array_free (GPtrArray *farray,
 		  gboolean   free_segment)
 {
+  GRealPtrArray *array = (GRealPtrArray*) farray;
   gpointer* segment;
+  gboolean preserve_wrapper;
 
   g_return_val_if_fail (array, NULL);
 
+  /* if others are holding a reference, preserve the wrapper but do free/return the data */
+  preserve_wrapper = FALSE;
+  if (g_atomic_int_get (&array->ref_count) > 1)
+    preserve_wrapper = TRUE;
+
   if (free_segment)
     {
+      if (array->element_free_func != NULL)
+        g_ptr_array_foreach (farray, (GFunc) array->element_free_func, NULL);
       g_free (array->pdata);
       segment = NULL;
     }
   else
     segment = array->pdata;
 
-  g_slice_free1 (sizeof (GRealPtrArray), array);
+  if (preserve_wrapper)
+    {
+      array->pdata = NULL;
+      array->len = 0;
+      array->alloc = 0;
+    }
+  else
+    {
+      g_slice_free1 (sizeof (GRealPtrArray), array);
+    }
 
   return segment;
 }
@@ -646,6 +825,40 @@ guint8*	    g_byte_array_free     (GByteArray *array,
   return (guint8*) g_array_free ((GArray*) array, free_segment);
 }
 
+/**
+ * g_byte_array_ref:
+ * @array: A #GByteArray.
+ *
+ * Atomically increments the reference count of @array by one. This
+ * function is MT-safe and may be called from any thread.
+ *
+ * Returns: The passed in #GByteArray.
+ *
+ * Since: 2.22
+ **/
+GByteArray *
+g_byte_array_ref (GByteArray *array)
+{
+  return (GByteArray *) g_array_ref ((GArray *) array);
+}
+
+/**
+ * g_byte_array_unref:
+ * @array: A #GByteArray.
+ *
+ * Atomically decrements the reference count of @array by one. If the
+ * reference count drops to 0, all memory allocated by the array is
+ * released. This function is MT-safe and may be called from any
+ * thread.
+ *
+ * Since: 2.22
+ **/
+void
+g_byte_array_unref (GByteArray *array)
+{
+  g_array_unref ((GArray *) array);
+}
+
 GByteArray* g_byte_array_append   (GByteArray   *array,
 				   const guint8 *data,
 				   guint         len)
diff --git a/glib/garray.h b/glib/garray.h
index db00137..6bc51f7 100644
--- a/glib/garray.h
+++ b/glib/garray.h
@@ -76,6 +76,9 @@ GArray* g_array_sized_new         (gboolean          zero_terminated,
 				   guint             reserved_size);
 gchar*  g_array_free              (GArray           *array,
 				   gboolean          free_segment);
+GArray *g_array_ref               (GArray           *array);
+void    g_array_unref             (GArray           *array);
+guint   g_array_get_element_size  (GArray           *array);
 GArray* g_array_append_vals       (GArray           *array,
 				   gconstpointer     data,
 				   guint             len);
@@ -107,9 +110,14 @@ void    g_array_sort_with_data    (GArray           *array,
  */
 #define    g_ptr_array_index(array,index_) ((array)->pdata)[index_]
 GPtrArray* g_ptr_array_new                (void);
+GPtrArray* g_ptr_array_new_with_free_func (GDestroyNotify    element_free_func);
 GPtrArray* g_ptr_array_sized_new          (guint             reserved_size);
 gpointer*  g_ptr_array_free               (GPtrArray        *array,
 					   gboolean          free_seg);
+GPtrArray* g_ptr_array_ref                (GPtrArray        *array);
+void       g_ptr_array_unref              (GPtrArray        *array);
+void       g_ptr_array_set_free_func      (GPtrArray        *array,
+                                           GDestroyNotify    element_free_func);
 void       g_ptr_array_set_size           (GPtrArray        *array,
 					   gint              length);
 gpointer   g_ptr_array_remove_index       (GPtrArray        *array,
@@ -143,6 +151,8 @@ GByteArray* g_byte_array_new               (void);
 GByteArray* g_byte_array_sized_new         (guint             reserved_size);
 guint8*     g_byte_array_free              (GByteArray       *array,
 					    gboolean          free_segment);
+GByteArray *g_byte_array_ref               (GByteArray       *array);
+void        g_byte_array_unref             (GByteArray       *array);
 GByteArray* g_byte_array_append            (GByteArray       *array,
 					    const guint8     *data,
 					    guint             len);
diff --git a/glib/glib.symbols b/glib/glib.symbols
index ce6a148..f8410ca 100644
--- a/glib/glib.symbols
+++ b/glib/glib.symbols
@@ -17,6 +17,9 @@ g_array_append_vals
 g_array_free
 g_array_insert_vals
 g_array_new
+g_array_ref
+g_array_unref
+g_array_get_element_size
 g_array_prepend_vals
 g_array_remove_index
 g_array_remove_index_fast
@@ -27,6 +30,8 @@ g_array_sort
 g_array_sort_with_data
 g_byte_array_append
 g_byte_array_free
+g_byte_array_unref
+g_byte_array_ref
 g_byte_array_new
 g_byte_array_prepend
 g_byte_array_remove_index
@@ -39,7 +44,11 @@ g_byte_array_sort_with_data
 g_ptr_array_add
 g_ptr_array_foreach
 g_ptr_array_free
+g_ptr_array_unref
+g_ptr_array_ref
 g_ptr_array_new
+g_ptr_array_new_with_free_func
+g_ptr_array_set_free_func
 g_ptr_array_remove
 g_ptr_array_remove_fast
 g_ptr_array_remove_index
