https://bugzilla.gnome.org/show_bug.cgi?id=793819
---
 jni/src/AtkWrapper.c                               |    6 
 jni/src/AtkWrapper.h                               |    7 
 jni/src/jawaction.c                                |   63 ++++--
 jni/src/jawcomponent.c                             |   53 +++--
 jni/src/jaweditabletext.c                          |   58 ++++-
 jni/src/jawhyperlink.c                             |   52 +++--
 jni/src/jawhypertext.c                             |   34 ++-
 jni/src/jawimage.c                                 |   28 +-
 jni/src/jawimpl.c                                  |  100 +++++++--
 jni/src/jawimpl.h                                  |    2 
 jni/src/jawobject.c                                |   80 ++++++-
 jni/src/jawselection.c                             |   60 ++++-
 jni/src/jawtable.c                                 |  212 +++++++++++++++------
 jni/src/jawtablecell.c                             |   50 +++-
 jni/src/jawtext.c                                  |  116 ++++++++---
 jni/src/jawutil.c                                  |    1 
 jni/src/jawvalue.c                                 |   40 ++-
 wrapper/org/GNOME/Accessibility/AtkWrapper.java.in |   16 +
 18 files changed, 737 insertions(+), 241 deletions(-)

--- a/jni/src/jawimpl.c
+++ b/jni/src/jawimpl.c
@@ -109,9 +109,9 @@ object_table_insert (JNIEnv *jniEnv, job
                                           classAccessibleContext,
                                           "hashCode",
                                           "()I");
-  gint hash_key = (gint)(*jniEnv)->CallIntMethod(jniEnv, ac, jmid);
+  jaw_impl->hash_key = (gint)(*jniEnv)->CallIntMethod(jniEnv, ac, jmid);
   g_mutex_lock(&objectTableMutex);
-  g_hash_table_insert(objectTable, GINT_TO_POINTER(hash_key), GINT_TO_POINTER(jaw_impl));
+  g_hash_table_insert(objectTable, GINT_TO_POINTER(jaw_impl->hash_key), jaw_impl);
   g_mutex_unlock(&objectTableMutex);
 }
 
@@ -139,19 +139,51 @@ object_table_lookup (JNIEnv *jniEnv, job
 }
 
 static void
-object_table_remove(JNIEnv *jniEnv, jobject ac)
+object_table_remove(JNIEnv *jniEnv, JawImpl *jaw_impl)
 {
-  jclass classAccessibleContext = (*jniEnv)->FindClass( jniEnv,
-                                                       "javax/accessibility/AccessibleContext" );
-  jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
-                                          classAccessibleContext,
-                                          "hashCode",
-                                          "()I" );
-  gint hash_key = (gint)(*jniEnv)->CallIntMethod( jniEnv, ac, jmid );
+  g_mutex_lock(&objectTableMutex);
+  g_hash_table_remove(objectTable, GINT_TO_POINTER(jaw_impl->hash_key));
+  g_mutex_unlock(&objectTableMutex);
+}
+
+/* Called on completion of Java GC, take the opportunity to look for stale jaw_impl */
+void
+object_table_gc(JNIEnv *jniEnv)
+{
+  GHashTableIter iter;
+  gpointer key, value;
+  GSList *list = NULL, *cur, *next;
+  int n = 0;
 
   g_mutex_lock(&objectTableMutex);
-  g_hash_table_remove(objectTable, GINT_TO_POINTER(hash_key));
+  if (objectTable)
+  {
+    g_hash_table_iter_init(&iter, objectTable);
+    while (g_hash_table_iter_next(&iter, &key, &value))
+    {
+      n++;
+      JawImpl *jaw_impl = value;
+      if ((*jniEnv)->IsSameObject(jniEnv, jaw_impl->parent.acc_context, NULL))
+      {
+	/* Got garbage-collected, mark for dropping */
+	list = g_slist_prepend(list, jaw_impl);
+      }
+    }
+  }
   g_mutex_unlock(&objectTableMutex);
+  /* fprintf(stderr,"%d objects\n", n); */
+
+  n = 0;
+  for (cur = list; cur != NULL; cur = next)
+  {
+    n++;
+    JawImpl *jaw_impl = cur->data;
+    g_object_unref(G_OBJECT(cur->data));
+    next = g_slist_next(cur);
+    g_slist_free_1(cur);
+  }
+  /* fprintf(stderr,"%d dropped\n", n); */
+  (void) n;
 }
 
 GHashTable*
@@ -171,7 +203,7 @@ aggregate_interface(JNIEnv *jniEnv, JawO
 {
   JawImpl *jaw_impl = JAW_IMPL(tflag, jaw_obj);
 
-  jobject ac = jaw_obj->acc_context;
+  jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context);
   jaw_impl->ifaceTable = g_hash_table_new(NULL, NULL);
 
   if (tflag & INTERFACE_ACTION)
@@ -273,6 +305,8 @@ aggregate_interface(JNIEnv *jniEnv, JawO
                         (gpointer)INTERFACE_TABLE_CELL,
                         (gpointer)info);
   }
+
+  (*jniEnv)->DeleteGlobalRef(jniEnv, ac);
 }
 
 JawImpl*
@@ -280,6 +314,7 @@ jaw_impl_get_instance (JNIEnv *jniEnv, j
 {
   JawImpl *jaw_impl;
   jniEnv = jaw_util_get_jni_env();
+  jobject temp_ref;
 
   if (jniEnv == NULL)
     return NULL;
@@ -298,10 +333,11 @@ jaw_impl_get_instance (JNIEnv *jniEnv, j
     if (jaw_thread == g_thread_self())
       g_warning("jaw_impl_get_instance called from jaw_thread. If you are running a screen reader, this is expected\nIf you are not running a screen reader, please report this warning to the java-atk-wrapper package, explaining how to reproduce this warning\n");
 
-    jobject global_ac = (*jniEnv)->NewGlobalRef(jniEnv, ac);
-    if (global_ac != NULL)
+    temp_ref = (*jniEnv)->NewGlobalRef(jniEnv, ac);
+    if (temp_ref != NULL)
     {
-      guint tflag = jaw_util_get_tflag_from_jobj(jniEnv, global_ac);
+      jobject weak_ref = (*jniEnv)->NewWeakGlobalRef(jniEnv, temp_ref);
+      guint tflag = jaw_util_get_tflag_from_jobj(jniEnv, temp_ref);
       jaw_impl = (JawImpl*)g_object_new(JAW_TYPE_IMPL(tflag), NULL);
       if (jaw_impl != NULL)
       {
@@ -309,15 +345,17 @@ jaw_impl_get_instance (JNIEnv *jniEnv, j
 
         if (jaw_obj != NULL)
         {
-          jaw_obj->acc_context = global_ac;
+          jaw_obj->acc_context = weak_ref;
           jaw_obj->storedData = g_hash_table_new(g_str_hash, g_str_equal);
           aggregate_interface(jniEnv, jaw_obj, tflag);
           atk_object_initialize(ATK_OBJECT(jaw_impl), NULL);
-          object_table_insert(jniEnv, global_ac, jaw_impl);
+          object_table_insert(jniEnv, weak_ref, jaw_impl);
         } else
         {
           if (jaw_debug)
             g_warning("jaw_impl_get_instance: jaw_obj == NULL");
+          (*jniEnv)->DeleteGlobalRef(jniEnv, temp_ref);
+          (*jniEnv)->DeleteWeakGlobalRef(jniEnv, weak_ref);
           return NULL;
         }
       } else
@@ -325,6 +363,7 @@ jaw_impl_get_instance (JNIEnv *jniEnv, j
         if (jaw_debug)
           g_warning("jaw_impl_get_instance: jaw_impl == NULL");
       }
+      (*jniEnv)->DeleteGlobalRef(jniEnv, temp_ref);
     } else
     {
       if (jaw_debug)
@@ -535,14 +574,12 @@ static void
 jaw_impl_finalize(GObject *gobject)
 {
   JawObject *jaw_obj = JAW_OBJECT(gobject);
-  jobject global_ac = jaw_obj->acc_context;
-
   JawImpl *jaw_impl = (JawImpl*)jaw_obj;
 
   JNIEnv *jniEnv = jaw_util_get_jni_env();
-  object_table_remove( jniEnv, global_ac );
+  object_table_remove( jniEnv, jaw_impl );
 
-  (*jniEnv)->DeleteGlobalRef(jniEnv, global_ac);
+  (*jniEnv)->DeleteWeakGlobalRef(jniEnv, jaw_obj->acc_context);
   jaw_obj->acc_context = NULL;
 
   /* Interface finalize */
@@ -590,8 +627,8 @@ jaw_impl_initialize (AtkObject *atk_obj,
   ATK_OBJECT_CLASS(jaw_impl_parent_class)->initialize(atk_obj, data);
 
   JawObject *jaw_obj = JAW_OBJECT(atk_obj);
-  jobject ac = jaw_obj->acc_context;
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context);
 
   jclass classAtkWrapper = (*jniEnv)->FindClass(jniEnv,
                                                 "org/GNOME/Accessibility/AtkWrapper");
@@ -600,6 +637,7 @@ jaw_impl_initialize (AtkObject *atk_obj,
                                                 "registerPropertyChangeListener",
                                                 "(Ljavax/accessibility/AccessibleContext;)V");
   (*jniEnv)->CallStaticVoidMethod(jniEnv, classAtkWrapper, jmid, ac);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, ac);
 }
 
 static AtkObject*
@@ -611,8 +649,11 @@ jaw_impl_get_parent (AtkObject *atk_obj)
   }
 
   JawObject *jaw_obj = JAW_OBJECT(atk_obj);
-  jobject ac = jaw_obj->acc_context;
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context);
+  if (!ac) {
+    return NULL;
+  }
 
   jclass classAccessibleContext = (*jniEnv)->FindClass(jniEnv,
                                                        "javax/accessibility/AccessibleContext" );
@@ -621,6 +662,7 @@ jaw_impl_get_parent (AtkObject *atk_obj)
                                           "getAccessibleParent",
                                           "()Ljavax/accessibility/Accessible;");
   jobject jparent = (*jniEnv)->CallObjectMethod( jniEnv, ac, jmid );
+  (*jniEnv)->DeleteGlobalRef(jniEnv, ac);
   if (jparent != NULL )
   {
     jclass classAccessible = (*jniEnv)->FindClass(jniEnv,
@@ -644,8 +686,11 @@ static AtkObject*
 jaw_impl_ref_child (AtkObject *atk_obj, gint i)
 {
   JawObject *jaw_obj = JAW_OBJECT(atk_obj);
-  jobject ac = jaw_obj->acc_context;
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context);
+  if (!ac) {
+    return NULL;
+  }
 
   jclass classAccessibleContext = (*jniEnv)->FindClass(jniEnv,
                                                        "javax/accessibility/AccessibleContext" );
@@ -654,6 +699,7 @@ jaw_impl_ref_child (AtkObject *atk_obj,
                                           "getAccessibleChild",
                                           "(I)Ljavax/accessibility/Accessible;" );
   jobject jchild = (*jniEnv)->CallObjectMethod( jniEnv, ac, jmid, i );
+  (*jniEnv)->DeleteGlobalRef(jniEnv, ac);
   if (jchild == NULL)
   {
     return NULL;
@@ -774,8 +820,11 @@ jaw_impl_ref_relation_set (AtkObject *at
     return NULL;
 
   JawObject *jaw_obj = JAW_OBJECT(atk_obj);
-  jobject ac = jaw_obj->acc_context;
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context);
+  if (!ac) {
+    return NULL;
+  }
 
   jclass classAccessibleContext = (*jniEnv)->FindClass(jniEnv,
                                                        "javax/accessibility/AccessibleContext" );
@@ -784,6 +833,7 @@ jaw_impl_ref_relation_set (AtkObject *at
                                           "getAccessibleRelationSet",
                                           "()Ljavax/accessibility/AccessibleRelationSet;" );
   jobject jrel_set = (*jniEnv)->CallObjectMethod( jniEnv, ac, jmid );
+  (*jniEnv)->DeleteGlobalRef(jniEnv, ac);
 
   jclass classAccessibleRelationSet = (*jniEnv)->FindClass( jniEnv,
                                                            "javax/accessibility/AccessibleRelationSet");
--- a/jni/src/AtkWrapper.c
+++ b/jni/src/AtkWrapper.c
@@ -160,6 +160,12 @@ JNICALL Java_org_GNOME_Accessibility_Atk
   }
 }
 
+JNIEXPORT void
+JNICALL Java_org_GNOME_Accessibility_AtkWrapper_GC(JNIEnv *jniEnv)
+{
+  object_table_gc(jniEnv);
+}
+
 enum _SignalType {
   Sig_Text_Caret_Moved = 0,
   Sig_Text_Property_Changed_Insert = 1,
--- a/jni/src/AtkWrapper.h
+++ b/jni/src/AtkWrapper.h
@@ -23,6 +23,13 @@ JNIEXPORT void JNICALL Java_org_GNOME_Ac
 
 /*
  * Class:     org_GNOME_Accessibility_AtkWrapper
+ * Method:    GC
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_org_GNOME_Accessibility_AtkWrapper_GC(JNIEnv *);
+
+/*
+ * Class:     org_GNOME_Accessibility_AtkWrapper
  * Method:    focusNotify
  * Signature: (Ljavax/accessibility/AccessibleContext;)V
  */
--- a/jni/src/jawimpl.h
+++ b/jni/src/jawimpl.h
@@ -47,12 +47,14 @@ struct _JawImpl
 	JawObject parent;
 
 	GHashTable *ifaceTable;
+	gint hash_key;
 };
 
 JawImpl* jaw_impl_get_instance(JNIEnv*, jobject);
 JawImpl* jaw_impl_find_instance(JNIEnv*, jobject);
 GHashTable* jaw_impl_get_object_hash_table(void);
 GMutex* jaw_impl_get_object_hash_table_mutex(void);
+void object_table_gc(JNIEnv *jniEnv);
 
 GType jaw_impl_get_type (guint);
 AtkRelationType jaw_impl_get_atk_relation_type(JNIEnv *jniEnv, jstring jrel_key);
--- a/wrapper/org/GNOME/Accessibility/AtkWrapper.java.in
+++ b/wrapper/org/GNOME/Accessibility/AtkWrapper.java.in
@@ -26,6 +26,9 @@ import java.beans.*;
 import java.io.*;
 import javax.accessibility.*;
 import java.awt.Toolkit;
+import javax.management.*;
+import java.util.*;
+import java.lang.management.*;
 
 public class AtkWrapper {
   static boolean accessibilityEnabled = false;
@@ -42,6 +45,17 @@ public class AtkWrapper {
           break;
         }
       }
+
+      java.util.List<GarbageCollectorMXBean> gcbeans = ManagementFactory.getGarbageCollectorMXBeans();
+      for (GarbageCollectorMXBean gcbean : gcbeans) {
+	NotificationEmitter emitter = (NotificationEmitter) gcbean;
+	NotificationListener listener = new NotificationListener() {
+	  public void handleNotification(Notification notif, Object handback) {
+	    AtkWrapper.GC();
+	  }
+	};
+	emitter.addNotificationListener(listener, null, null);
+      }
     } catch (Exception e) {
       e.printStackTrace();
       e.getCause();
@@ -634,6 +649,7 @@ public class AtkWrapper {
 
   public native static boolean initNativeLibrary();
   public native static void loadAtkBridge();
+  public native static void GC();
 
   public native static void focusNotify(javax.accessibility.AccessibleContext ac);
 
--- a/jni/src/jawobject.c
+++ b/jni/src/jawobject.c
@@ -205,8 +205,11 @@ static AtkObject* jaw_object_get_parent(
   }
 
   JawObject *jaw_obj = JAW_OBJECT(atk_obj);
-  jobject ac = jaw_obj->acc_context;
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context);
+  if (!ac) {
+    return NULL;
+  }
 
   jclass classAccessibleContext = (*jniEnv)->FindClass(jniEnv,
                                                        "javax/accessibility/AccessibleContext" );
@@ -215,6 +218,7 @@ static AtkObject* jaw_object_get_parent(
                                           "getAccessibleParent",
                                           "()Ljavax/accessibility/AccessibleContext;");
   jobject jparent = (*jniEnv)->CallObjectMethod( jniEnv, ac, jmid );
+  (*jniEnv)->DeleteGlobalRef(jniEnv, ac);
   if (jparent != NULL )
   {
     jclass classAccessible = (*jniEnv)->FindClass(jniEnv,
@@ -235,8 +239,11 @@ static void
 jaw_object_set_parent(AtkObject *atk_obj, AtkObject *parent)
 {
   JawObject *jaw_obj = JAW_OBJECT(atk_obj);
-  jobject ac = jaw_obj->acc_context;
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context);
+  if (!ac) {
+    return;
+  }
 
   jclass classAccessibleContext = (*jniEnv)->FindClass(jniEnv,
                                                        "javax/accessibility/AccessibleContext" );
@@ -245,6 +252,7 @@ jaw_object_set_parent(AtkObject *atk_obj
                                           "setAccessibleParent",
                                           "(Ljavax/accessibility/AccessibleContext;)");
   jobject jparent = (*jniEnv)->CallObjectMethod( jniEnv, ac, jmid );
+  (*jniEnv)->DeleteGlobalRef(jniEnv, ac);
   if (jparent != NULL )
   {
     jclass classAccessible = (*jniEnv)->FindClass(jniEnv,
@@ -264,8 +272,11 @@ static const gchar*
 jaw_object_get_name (AtkObject *atk_obj)
 {
   JawObject *jaw_obj = JAW_OBJECT(atk_obj);
-  jobject ac = jaw_obj->acc_context;
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context);
+  if (!ac) {
+    return NULL;
+  }
 
   atk_obj->name = (gchar *)ATK_OBJECT_CLASS (parent_class)->get_name (atk_obj);
 
@@ -290,6 +301,7 @@ jaw_object_get_name (AtkObject *atk_obj)
                                           "getAccessibleName",
                                           "()Ljava/lang/String;");
   jstring jstr = (*jniEnv)->CallObjectMethod( jniEnv, ac, jmid );
+  (*jniEnv)->DeleteGlobalRef(jniEnv, ac);
 
   if (atk_obj->name != NULL)
   {
@@ -312,8 +324,11 @@ jaw_object_get_name (AtkObject *atk_obj)
 static void jaw_object_set_name (AtkObject *atk_obj, const gchar *name)
 {
   JawObject *jaw_obj = JAW_OBJECT(atk_obj);
-  jobject ac = jaw_obj->acc_context;
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context);
+  if (!ac) {
+    return;
+  }
 
   atk_obj->name = (gchar *)ATK_OBJECT_CLASS (parent_class)->get_name (atk_obj);
 
@@ -324,6 +339,7 @@ static void jaw_object_set_name (AtkObje
                                           "setAccessibleName",
                                           "(Ljava/lang/String;)");
   jstring jstr = (*jniEnv)->CallObjectMethod( jniEnv, ac, jmid );
+  (*jniEnv)->DeleteGlobalRef(jniEnv, ac);
 
   if (atk_obj->name != NULL)
   {
@@ -349,8 +365,11 @@ static const gchar*
 jaw_object_get_description (AtkObject *atk_obj)
 {
   JawObject *jaw_obj = JAW_OBJECT(atk_obj);
-  jobject ac = jaw_obj->acc_context;
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context);
+  if (!ac) {
+    return NULL;
+  }
 
   jclass classAccessibleContext = (*jniEnv)->FindClass( jniEnv,
                                                        "javax/accessibility/AccessibleContext" );
@@ -359,6 +378,7 @@ jaw_object_get_description (AtkObject *a
                                           "getAccessibleDescription",
                                           "()Ljava/lang/String;");
   jstring jstr = (*jniEnv)->CallObjectMethod( jniEnv, ac, jmid );
+  (*jniEnv)->DeleteGlobalRef(jniEnv, ac);
 
   if (atk_obj->description != NULL)
   {
@@ -381,8 +401,11 @@ jaw_object_get_description (AtkObject *a
 static void jaw_object_set_description (AtkObject *atk_obj, const gchar *description)
 {
   JawObject *jaw_obj = JAW_OBJECT(atk_obj);
-  jobject ac = jaw_obj->acc_context;
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context);
+  if (!ac) {
+    return;
+  }
 
   jclass classAccessibleContext = (*jniEnv)->FindClass( jniEnv,
                                                        "javax/accessibility/AccessibleContext" );
@@ -391,6 +414,7 @@ static void jaw_object_set_description (
                                           "setAccessibleDescription",
                                           "(Ljava/lang/String;)");
   jstring jstr = (*jniEnv)->CallObjectMethod( jniEnv, ac, jmid );
+  (*jniEnv)->DeleteGlobalRef(jniEnv, ac);
 
   if (description != NULL)
   {
@@ -417,8 +441,11 @@ static gint
 jaw_object_get_n_children (AtkObject *atk_obj)
 {
   JawObject *jaw_obj = JAW_OBJECT(atk_obj);
-  jobject ac = jaw_obj->acc_context;
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context);
+  if (!ac) {
+    return 0;
+  }
 
   jclass classAccessibleContext = (*jniEnv)->FindClass(jniEnv,
                                                        "javax/accessibility/AccessibleContext" );
@@ -427,6 +454,7 @@ jaw_object_get_n_children (AtkObject *at
                                           "getAccessibleChildrenCount",
                                           "()I");
   jint count = (*jniEnv)->CallIntMethod( jniEnv, ac, jmid );
+  (*jniEnv)->DeleteGlobalRef(jniEnv, ac);
 
   return (gint)count;
 }
@@ -440,8 +468,11 @@ jaw_object_get_index_in_parent (AtkObjec
   }
 
   JawObject *jaw_obj = JAW_OBJECT(atk_obj);
-  jobject ac = jaw_obj->acc_context;
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context);
+  if (!ac) {
+    return 0;
+  }
 
   jclass classAccessibleContext = (*jniEnv)->FindClass(jniEnv,
                                                        "javax/accessibility/AccessibleContext" );
@@ -450,6 +481,7 @@ jaw_object_get_index_in_parent (AtkObjec
                                           "getAccessibleIndexInParent",
                                           "()I");
   jint index = (*jniEnv)->CallIntMethod( jniEnv, ac, jmid );
+  (*jniEnv)->DeleteGlobalRef(jniEnv, ac);
 
   return (gint)index;
 }
@@ -458,7 +490,13 @@ static AtkRole
 jaw_object_get_role (AtkObject *atk_obj)
 {
   JawObject *jaw_obj = JAW_OBJECT(atk_obj);
-  atk_obj->role = jaw_util_get_atk_role_from_jobj(jaw_obj->acc_context);
+  JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context);
+  if (!ac) {
+    return 0;
+  }
+  atk_obj->role = jaw_util_get_atk_role_from_jobj(ac);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, ac);
   return atk_obj->role;
 }
 
@@ -477,8 +515,11 @@ jaw_object_ref_state_set (AtkObject *atk
   AtkStateSet* state_set = jaw_obj->state_set;
   atk_state_set_clear_states( state_set );
 
-  jobject ac = jaw_obj->acc_context;
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context);
+  if (!ac) {
+    return NULL;
+  }
   jclass classAccessibleContext = (*jniEnv)->FindClass(jniEnv,
                                                        "javax/accessibility/AccessibleContext" );
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -486,6 +527,7 @@ jaw_object_ref_state_set (AtkObject *atk
                                           "getAccessibleStateSet",
                                           "()Ljavax/accessibility/AccessibleStateSet;" );
   jobject jstate_set = (*jniEnv)->CallObjectMethod( jniEnv, ac, jmid );
+  (*jniEnv)->DeleteGlobalRef(jniEnv, ac);
   if (jstate_set == NULL)
     return NULL;
 
@@ -520,8 +562,11 @@ jaw_object_ref_state_set (AtkObject *atk
 static const gchar *jaw_object_get_object_locale (AtkObject *atk_obj)
 {
   JawObject *jaw_obj = JAW_OBJECT(atk_obj);
-  jobject ac = jaw_obj->acc_context;
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context);
+  if (!ac) {
+    return NULL;
+  }
 
   jclass classAccessibleContext = (*jniEnv)->FindClass(jniEnv,
                                                        "javax/accessibility/AccessibleContext" );
@@ -530,6 +575,7 @@ static const gchar *jaw_object_get_objec
                                           "getLocale",
                                           "()Ljavax/accessibility/AccessibleContext;");
   jobject locale = (*jniEnv)->CallObjectMethod( jniEnv, ac, jmid );
+  (*jniEnv)->DeleteGlobalRef(jniEnv, ac);
   JawImpl *target_obj = jaw_impl_get_instance(jniEnv, locale);
   if(target_obj == NULL)
     return NULL;
@@ -547,8 +593,11 @@ jaw_object_ref_relation_set (AtkObject *
     return NULL;
 
   JawObject *jaw_obj = JAW_OBJECT(atk_obj);
-  jobject ac = jaw_obj->acc_context;
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context);
+  if (!ac) {
+    return NULL;
+  }
 
   jclass classAccessibleContext = (*jniEnv)->FindClass(jniEnv,
                                                        "javax/accessibility/AccessibleContext" );
@@ -557,6 +606,7 @@ jaw_object_ref_relation_set (AtkObject *
                                           "getAccessibleRelationSet",
                                           "()Ljavax/accessibility/AccessibleRelationSet;" );
   jobject jrel_set = (*jniEnv)->CallObjectMethod( jniEnv, ac, jmid );
+  (*jniEnv)->DeleteGlobalRef(jniEnv, ac);
 
   jclass classAccessibleRelationSet = (*jniEnv)->FindClass( jniEnv,
                                                            "javax/accessibility/AccessibleRelationSet");
@@ -620,8 +670,11 @@ static AtkObject*
 jaw_object_ref_child(AtkObject *atk_obj, gint i)
 {
   JawObject *jaw_obj = JAW_OBJECT(atk_obj);
-  jobject ac = jaw_obj->acc_context;
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject ac = (*jniEnv)->NewGlobalRef(jniEnv, jaw_obj->acc_context);
+  if (!ac) {
+    return NULL;
+  }
 
   jclass classAccessibleContext = (*jniEnv)->FindClass(jniEnv,
                                                        "javax/accessibility/AccessibleContext" );
@@ -630,6 +683,7 @@ jaw_object_ref_child(AtkObject *atk_obj,
                                           "getAccessibleChild",
                                           "(I)Ljavax/accessibility/Accessible;" );
   jobject jchild = (*jniEnv)->CallObjectMethod( jniEnv, ac, jmid, i );
+  (*jniEnv)->DeleteGlobalRef(jniEnv, ac);
   if (jchild == NULL)
   {
     return NULL;
--- a/jni/src/jawaction.c
+++ b/jni/src/jawaction.c
@@ -70,7 +70,7 @@ jaw_action_data_init (jobject ac)
                                           "<init>",
                                           "(Ljavax/accessibility/AccessibleContext;)V");
   jobject jatk_action = (*jniEnv)->NewObject(jniEnv, classAction, jmid, ac);
-  data->atk_action = (*jniEnv)->NewGlobalRef(jniEnv, jatk_action);
+  data->atk_action = (*jniEnv)->NewWeakGlobalRef(jniEnv, jatk_action);
 
   return data;
 }
@@ -115,7 +115,7 @@ jaw_action_data_finalize (gpointer p)
       data->action_keybinding = NULL;
     }
 
-    (*jniEnv)->DeleteGlobalRef(jniEnv, data->atk_action);
+    (*jniEnv)->DeleteWeakGlobalRef(jniEnv, data->atk_action);
     data->atk_action = NULL;
   }
 }
@@ -125,9 +125,12 @@ jaw_action_do_action (AtkAction *action,
 {
   JawObject *jaw_obj = JAW_OBJECT(action);
   ActionData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_ACTION);
-  jobject atk_action = data->atk_action;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_action = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_action);
+  if (!atk_action) {
+    return FALSE;
+  }
+
   jclass classAtkAction = (*jniEnv)->FindClass(jniEnv,
                                                "org/GNOME/Accessibility/AtkAction");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -138,6 +141,7 @@ jaw_action_do_action (AtkAction *action,
                                                   atk_action,
                                                   jmid,
                                                   (jint)i);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_action);
 
   if (jresult == JNI_TRUE)
     return TRUE;
@@ -150,16 +154,21 @@ jaw_action_get_n_actions (AtkAction *act
 {
   JawObject *jaw_obj = JAW_OBJECT(action);
   ActionData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_ACTION);
-  jobject atk_action = data->atk_action;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_action = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_action);
+  if (!atk_action) {
+    return 0;
+  }
+
   jclass classAtkAction = (*jniEnv)->FindClass(jniEnv,
                                                "org/GNOME/Accessibility/AtkAction");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
                                           classAtkAction,
                                           "get_n_actions", "()I");
 
-  return (gint)(*jniEnv)->CallIntMethod(jniEnv, atk_action, jmid);
+  gint ret = (gint)(*jniEnv)->CallIntMethod(jniEnv, atk_action, jmid);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_action);
+  return ret;
 }
 
 static const gchar*
@@ -167,9 +176,12 @@ jaw_action_get_description (AtkAction *a
 {
   JawObject *jaw_obj = JAW_OBJECT(action);
   ActionData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_ACTION);
-  jobject atk_action = data->atk_action;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_action = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_action);
+  if (!atk_action) {
+    return NULL;
+  }
+
   jclass classAtkAction = (*jniEnv)->FindClass(jniEnv,
                                                "org/GNOME/Accessibility/AtkAction");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -180,6 +192,7 @@ jaw_action_get_description (AtkAction *a
                                              atk_action,
                                              jmid,
                                              (jint)i);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_action);
 
   if (data->action_description != NULL)
   {
@@ -202,9 +215,12 @@ jaw_action_set_description (AtkAction *a
 {
   JawObject *jaw_obj = JAW_OBJECT(action);
   ActionData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_ACTION);
-  jobject atk_action = data->atk_action;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_action = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_action);
+  if (!atk_action) {
+    return FALSE;
+  }
+
   jclass classAtkAction = (*jniEnv)->FindClass(jniEnv,
                                                "org/GNOME/Accessibility/AtkAction");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -216,6 +232,7 @@ jaw_action_set_description (AtkAction *a
                                                  jmid,
                                                  (jint)i,
                                                  (jstring)description);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_action);
 
   if (jisset == JNI_TRUE)
   {
@@ -230,9 +247,12 @@ jaw_action_get_name (AtkAction *action,
 {
   JawObject *jaw_obj = JAW_OBJECT(action);
   ActionData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_ACTION);
-  jobject atk_action = data->atk_action;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_action = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_action);
+  if (!atk_action) {
+    return NULL;
+  }
+
   jclass classAtkAction = (*jniEnv)->FindClass(jniEnv,
                                                "org/GNOME/Accessibility/AtkAction");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -240,6 +260,7 @@ jaw_action_get_name (AtkAction *action,
                                           "get_name",
                                           "(I)Ljava/lang/String;");
   jstring jstr = (*jniEnv)->CallObjectMethod(jniEnv, atk_action, jmid, (jint)i);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_action);
 
   if (data->action_name != NULL)
   {
@@ -262,15 +283,19 @@ jaw_action_get_localized_name (AtkAction
 {
   JawObject *jaw_obj = JAW_OBJECT(action);
   ActionData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_ACTION);
-  jobject atk_action = data->atk_action;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_action = (*env)->NewGlobalRef(env, data->atk_action);
+  if (!atk_action) {
+    return NULL;
+  }
+
   jclass classAtkAction = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkAction");
   jmethodID jmid = (*env)->GetMethodID(env,
                                        classAtkAction,
                                        "getLocalizedName",
                                        "(I)Ljava/lang/String;");
   jstring jstr = (*env)->CallObjectMethod(env, atk_action, jmid, (jint)i);
+  (*env)->DeleteGlobalRef(env, atk_action);
   if (data->action_name != NULL)
   {
     (*env)->ReleaseStringUTFChars(env, data->jstrLocalizedName, data->action_name);
@@ -289,9 +314,12 @@ jaw_action_get_keybinding (AtkAction *ac
     return NULL;
 
   ActionData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_ACTION);
-  jobject atk_action = data->atk_action;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_action = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_action);
+  if (!atk_action) {
+    return NULL;
+  }
+
   jclass classAtkAction = (*jniEnv)->FindClass(jniEnv,
                                                "org/GNOME/Accessibility/AtkAction");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -299,6 +327,7 @@ jaw_action_get_keybinding (AtkAction *ac
                                           "get_keybinding",
                                           "(I)Ljava/lang/String;");
   jstring jstr = (*jniEnv)->CallObjectMethod(jniEnv, atk_action, jmid, (jint)i);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_action);
 
   if (data->action_keybinding != NULL)
   {
--- a/jni/src/jawcomponent.c
+++ b/jni/src/jawcomponent.c
@@ -86,7 +86,7 @@ jaw_component_data_init (jobject ac)
                                           "(Ljavax/accessibility/AccessibleContext;)V");
 
   jobject jatk_component = (*jniEnv)->NewObject(jniEnv, classComponent, jmid, ac);
-  data->atk_component = (*jniEnv)->NewGlobalRef(jniEnv, jatk_component);
+  data->atk_component = (*jniEnv)->NewWeakGlobalRef(jniEnv, jatk_component);
 
   return data;
 }
@@ -99,7 +99,7 @@ jaw_component_data_finalize (gpointer p)
 
   if (data && data->atk_component)
   {
-    (*jniEnv)->DeleteGlobalRef(jniEnv, data->atk_component);
+    (*jniEnv)->DeleteWeakGlobalRef(jniEnv, data->atk_component);
     data->atk_component = NULL;
   }
 }
@@ -131,9 +131,12 @@ jaw_component_contains (AtkComponent *co
 {
   JawObject *jaw_obj = JAW_OBJECT(component);
   ComponentData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_COMPONENT);
-  jobject atk_component = data->atk_component;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_component = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_component);
+  if (!atk_component) {
+    return FALSE;
+  }
+
   jclass classAtkComponent = (*jniEnv)->FindClass(jniEnv,
                                                   "org/GNOME/Accessibility/AtkComponent");
 
@@ -148,6 +151,7 @@ jaw_component_contains (AtkComponent *co
                                                     (jint)x,
                                                     (jint)y,
                                                     (jint)coord_type);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_component);
 
   if (jcontains == JNI_TRUE)
   {
@@ -162,9 +166,12 @@ jaw_component_ref_accessible_at_point (A
 {
   JawObject *jaw_obj = JAW_OBJECT(component);
   ComponentData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_COMPONENT);
-  jobject atk_component = data->atk_component;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_component = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_component);
+  if (!atk_component) {
+    return NULL;
+  }
+
   jclass classAtkComponent = (*jniEnv)->FindClass(jniEnv,
                                                   "org/GNOME/Accessibility/AtkComponent");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -177,6 +184,7 @@ jaw_component_ref_accessible_at_point (A
                                                  (jint)x,
                                                  (jint)y,
                                                  (jint)coord_type);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_component);
 
   JawImpl* jaw_impl = jaw_impl_get_instance( jniEnv, child_ac );
 
@@ -202,9 +210,12 @@ jaw_component_get_extents (AtkComponent
   JawObject *jaw_obj = JAW_OBJECT(component);
   ComponentData *data = jaw_object_get_interface_data(jaw_obj,
                                                       INTERFACE_COMPONENT);
-  jobject atk_component = data->atk_component;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_component = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_component);
+  if (!atk_component) {
+    return;
+  }
+
   jclass classAtkComponent = (*jniEnv)->FindClass(jniEnv,
                                                   "org/GNOME/Accessibility/AtkComponent");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -213,6 +224,7 @@ jaw_component_get_extents (AtkComponent
                                           "()Ljava/awt/Rectangle;");
 
   jobject jrectangle = (*jniEnv)->CallObjectMethod(jniEnv, atk_component, jmid);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_component);
 
   if (jrectangle == NULL)
   {
@@ -245,9 +257,12 @@ jaw_component_set_extents (AtkComponent
 
   JawObject *jaw_obj = JAW_OBJECT(component);
   ComponentData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_COMPONENT);
-  jobject atk_component = data->atk_component;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_component = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_component);
+  if (!atk_component) {
+    return FALSE;
+  }
+
   jclass classAtkComponent = (*jniEnv)->FindClass(jniEnv,
                                                   "org/GNOME/Accessibility/AtkComponent");
 
@@ -271,6 +286,7 @@ jaw_component_set_extents (AtkComponent
     height = 0;
     x = 0;
     y = 0;
+    (*jniEnv)->DeleteGlobalRef(jniEnv, atk_component);
     return FALSE;
   }
 
@@ -293,6 +309,7 @@ jaw_component_set_extents (AtkComponent
                                                atk_component,
                                                "height",
                                                "I");
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_component);
 
   jint jwidth = (*jniEnv)->GetIntField(jniEnv, classRectangle, jfidWidth);
   jint jheight = (*jniEnv)->GetIntField(jniEnv, classRectangle, jfidHeight);
@@ -312,9 +329,12 @@ jaw_component_grab_focus (AtkComponent *
 {
   JawObject *jaw_obj = JAW_OBJECT(component);
   ComponentData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_COMPONENT);
-  jobject atk_component = data->atk_component;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_component = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_component);
+  if (!atk_component) {
+    return FALSE;
+  }
+
   jclass classAtkComponent = (*jniEnv)->FindClass(jniEnv,
                                                   "org/GNOME/Accessibility/AtkComponent");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -322,6 +342,7 @@ jaw_component_grab_focus (AtkComponent *
                                           "grab_focus",
                                           "()Z");
   jboolean jresult = (*jniEnv)->CallBooleanMethod(jniEnv, atk_component, jmid);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_component);
 
   if (jresult == JNI_TRUE)
   {
@@ -337,9 +358,12 @@ jaw_component_get_layer (AtkComponent *c
   JawObject *jaw_obj = JAW_OBJECT(component);
   ComponentData *data = jaw_object_get_interface_data(jaw_obj,
                                                       INTERFACE_COMPONENT);
-  jobject atk_component = data->atk_component;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_component = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_component);
+  if (!atk_component) {
+    return 0;
+  }
+
   jclass classAtkComponent = (*jniEnv)->FindClass(jniEnv,
                                                   "org/GNOME/Accessibility/AtkComponent");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -348,6 +372,7 @@ jaw_component_get_layer (AtkComponent *c
                                           "()I");
 
   jint jlayer = (*jniEnv)->CallIntMethod(jniEnv, atk_component, jmid);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_component);
 
   return (AtkLayer)jlayer;
 }
--- a/jni/src/jaweditabletext.c
+++ b/jni/src/jaweditabletext.c
@@ -82,7 +82,7 @@ jaw_editable_text_data_init (jobject ac)
                                                     classEditableText,
                                                     jmid,
                                                     ac);
-  data->atk_editable_text = (*jniEnv)->NewGlobalRef(jniEnv,
+  data->atk_editable_text = (*jniEnv)->NewWeakGlobalRef(jniEnv,
                                                     jatk_editable_text);
 
   return data;
@@ -96,7 +96,7 @@ jaw_editable_text_data_finalize (gpointe
 
   if (data && data->atk_editable_text)
   {
-    (*jniEnv)->DeleteGlobalRef(jniEnv, data->atk_editable_text);
+    (*jniEnv)->DeleteWeakGlobalRef(jniEnv, data->atk_editable_text);
     data->atk_editable_text = NULL;
   }
 }
@@ -107,9 +107,12 @@ jaw_editable_text_set_text_contents (Atk
 {
   JawObject *jaw_obj = JAW_OBJECT(text);
   EditableTextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_EDITABLE_TEXT);
-  jobject atk_editable_text = data->atk_editable_text;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_editable_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_editable_text);
+  if (!atk_editable_text) {
+    return;
+  }
+
   jclass classAtkEditableText = (*jniEnv)->FindClass(jniEnv,
                                                      "org/GNOME/Accessibility/AtkEditableText");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -119,6 +122,7 @@ jaw_editable_text_set_text_contents (Atk
 
   jstring jstr = (*jniEnv)->NewStringUTF(jniEnv, string);
   (*jniEnv)->CallVoidMethod(jniEnv, atk_editable_text, jmid, jstr);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_editable_text);
 }
 
 void
@@ -129,9 +133,12 @@ jaw_editable_text_insert_text (AtkEditab
 {
   JawObject *jaw_obj = JAW_OBJECT(text);
   EditableTextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_EDITABLE_TEXT);
-  jobject atk_editable_text = data->atk_editable_text;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_editable_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_editable_text);
+  if (!atk_editable_text) {
+    return;
+  }
+
   jclass classAtkEditableText = (*jniEnv)->FindClass(jniEnv,
                                                      "org/GNOME/Accessibility/AtkEditableText");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -144,6 +151,7 @@ jaw_editable_text_insert_text (AtkEditab
                             atk_editable_text,
                             jmid, jstr,
                             (jint)*position);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_editable_text);
   *position = *position + length;
   atk_text_set_caret_offset(ATK_TEXT(jaw_obj), *position);
 }
@@ -156,9 +164,12 @@ jaw_editable_text_copy_text (AtkEditable
   JawObject *jaw_obj = JAW_OBJECT(text);
   EditableTextData *data = jaw_object_get_interface_data(jaw_obj,
                                                          INTERFACE_EDITABLE_TEXT);
-  jobject atk_editable_text = data->atk_editable_text;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_editable_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_editable_text);
+  if (!atk_editable_text) {
+    return;
+  }
+
   jclass classAtkEditableText = (*jniEnv)->FindClass(jniEnv,
                                                      "org/GNOME/Accessibility/AtkEditableText");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -170,6 +181,7 @@ jaw_editable_text_copy_text (AtkEditable
                             jmid,
                             (jint)start_pos,
                             (jint)end_pos);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_editable_text);
 }
 
 void
@@ -178,9 +190,12 @@ jaw_editable_text_cut_text (AtkEditableT
 {
   JawObject *jaw_obj = JAW_OBJECT(text);
   EditableTextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_EDITABLE_TEXT);
-  jobject atk_editable_text = data->atk_editable_text;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_editable_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_editable_text);
+  if (!atk_editable_text) {
+    return;
+  }
+
   jclass classAtkEditableText = (*jniEnv)->FindClass(jniEnv,
                                                      "org/GNOME/Accessibility/AtkEditableText");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -192,6 +207,7 @@ jaw_editable_text_cut_text (AtkEditableT
                             jmid,
                             (jint)start_pos,
                             (jint)end_pos);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_editable_text);
 }
 
 void
@@ -202,9 +218,12 @@ jaw_editable_text_delete_text (AtkEditab
   JawObject *jaw_obj = JAW_OBJECT(text);
   EditableTextData *data = jaw_object_get_interface_data(jaw_obj,
                                                          INTERFACE_EDITABLE_TEXT);
-  jobject atk_editable_text = data->atk_editable_text;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_editable_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_editable_text);
+  if (!atk_editable_text) {
+    return;
+  }
+
   jclass classAtkEditableText = (*jniEnv)->FindClass(jniEnv,
                                                      "org/GNOME/Accessibility/AtkEditableText");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -216,6 +235,7 @@ jaw_editable_text_delete_text (AtkEditab
                             jmid,
                             (jint)start_pos,
                             (jint)end_pos);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_editable_text);
 }
 
 void
@@ -225,9 +245,12 @@ jaw_editable_text_paste_text (AtkEditabl
   JawObject *jaw_obj = JAW_OBJECT(text);
   EditableTextData *data = jaw_object_get_interface_data(jaw_obj,
                                                          INTERFACE_EDITABLE_TEXT);
-  jobject atk_editable_text = data->atk_editable_text;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_editable_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_editable_text);
+  if (!atk_editable_text) {
+    return;
+  }
+
   jclass classAtkEditableText = (*jniEnv)->FindClass(jniEnv,
                                                      "org/GNOME/Accessibility/AtkEditableText");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -238,6 +261,7 @@ jaw_editable_text_paste_text (AtkEditabl
                             atk_editable_text,
                             jmid,
                             (jint)position);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_editable_text);
 }
 
 static gboolean
@@ -248,8 +272,11 @@ jaw_editable_text_set_run_attributes(Atk
 {
   JawObject *jaw_obj = JAW_OBJECT(text);
   EditableTextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_EDITABLE_TEXT);
-  jobject atk_editable_text = data->atk_editable_text;
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_editable_text = (*env)->NewGlobalRef(env, data->atk_editable_text);
+  if (!atk_editable_text) {
+    return FALSE;
+  }
   jclass classAtkEditableText = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkEditableText");
   jmethodID jmid = (*env)->GetMethodID(env,
                                                                    classAtkEditableText,
@@ -261,6 +288,7 @@ jaw_editable_text_set_run_attributes(Atk
                                                                             (jobject)attrib_set,
                                                                             (jint)start_offset,
                                                                             (jint)end_offset);
+  (*env)->DeleteGlobalRef(env, atk_editable_text);
   if (jresult == JNI_TRUE)
     return TRUE;
 
--- a/jni/src/jawhyperlink.c
+++ b/jni/src/jawhyperlink.c
@@ -43,7 +43,7 @@ jaw_hyperlink_new (jobject jhyperlink)
 {
 	JawHyperlink* jaw_hyperlink = g_object_new(JAW_TYPE_HYPERLINK, NULL);
 	JNIEnv *jniEnv = jaw_util_get_jni_env();
-	jaw_hyperlink->jhyperlink = (*jniEnv)->NewGlobalRef(jniEnv, jhyperlink);
+	jaw_hyperlink->jhyperlink = (*jniEnv)->NewWeakGlobalRef(jniEnv, jhyperlink);
 
 	return jaw_hyperlink;
 }
@@ -82,7 +82,7 @@ jaw_hyperlink_finalize(GObject *gobject)
 	JawHyperlink *jaw_hyperlink = JAW_HYPERLINK(gobject);
 
 	JNIEnv *jniEnv = jaw_util_get_jni_env();
-	(*jniEnv)->DeleteGlobalRef(jniEnv, jaw_hyperlink->jhyperlink);
+	(*jniEnv)->DeleteWeakGlobalRef(jniEnv, jaw_hyperlink->jhyperlink);
 	jaw_hyperlink->jhyperlink = NULL;
 
 	/* Chain up to parent's finalize */
@@ -94,12 +94,16 @@ jaw_hyperlink_get_uri (AtkHyperlink *atk
 			gint i)
 {
 	JawHyperlink *jaw_hyperlink = JAW_HYPERLINK(atk_hyperlink);
-	jobject jhyperlink = jaw_hyperlink->jhyperlink;
-
 	JNIEnv *jniEnv = jaw_util_get_jni_env();
+	jobject jhyperlink = (*jniEnv)->NewGlobalRef(jniEnv, jaw_hyperlink->jhyperlink);
+	if (!jhyperlink) {
+		return NULL;
+	}
+
 	jclass classAtkHyperlink = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkHyperlink");
 	jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkHyperlink, "get_uri", "(I)Ljava/lang/String;");
 	jstring jstr = (*jniEnv)->CallObjectMethod(jniEnv, jhyperlink, jmid, (jint)i);
+	(*jniEnv)->DeleteGlobalRef(jniEnv, jhyperlink);
 	
 	if (jaw_hyperlink->uri != NULL) {
 		(*jniEnv)->ReleaseStringUTFChars(jniEnv, jaw_hyperlink->jstrUri, jaw_hyperlink->uri);
@@ -117,12 +121,16 @@ jaw_hyperlink_get_object (AtkHyperlink *
 			gint i)
 {
 	JawHyperlink *jaw_hyperlink = JAW_HYPERLINK(atk_hyperlink);
-	jobject jhyperlink = jaw_hyperlink->jhyperlink;
-
 	JNIEnv *jniEnv = jaw_util_get_jni_env();
+	jobject jhyperlink = (*jniEnv)->NewGlobalRef(jniEnv, jaw_hyperlink->jhyperlink);
+	if (!jhyperlink) {
+		return NULL;
+	}
+
 	jclass classAtkHyperlink = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkHyperlink");
 	jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkHyperlink, "get_object", "(I)Ljava/lang/String;");
 	jobject jobj = (*jniEnv)->CallObjectMethod(jniEnv, jhyperlink, jmid, (jint)i);
+	(*jniEnv)->DeleteGlobalRef(jniEnv, jhyperlink);
 	if (jobj == NULL) {
 		return NULL;
 	}
@@ -140,12 +148,16 @@ static gint
 jaw_hyperlink_get_end_index (AtkHyperlink *atk_hyperlink)
 {
 	JawHyperlink *jaw_hyperlink = JAW_HYPERLINK(atk_hyperlink);
-	jobject jhyperlink = jaw_hyperlink->jhyperlink;
-
 	JNIEnv *jniEnv = jaw_util_get_jni_env();
+	jobject jhyperlink = (*jniEnv)->NewGlobalRef(jniEnv, jaw_hyperlink->jhyperlink);
+	if (!jhyperlink) {
+		return 0;
+	}
+
 	jclass classAtkHyperlink = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkHyperlink");
 	jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkHyperlink, "get_end_index", "()I");
 	jint jindex = (*jniEnv)->CallIntMethod(jniEnv, jhyperlink, jmid);
+	(*jniEnv)->DeleteGlobalRef(jniEnv, jhyperlink);
 
 	return jindex;
 }
@@ -153,12 +165,16 @@ jaw_hyperlink_get_end_index (AtkHyperlin
 static gint jaw_hyperlink_get_start_index (AtkHyperlink	*atk_hyperlink)
 {
 	JawHyperlink *jaw_hyperlink = JAW_HYPERLINK(atk_hyperlink);
-	jobject jhyperlink = jaw_hyperlink->jhyperlink;
-
 	JNIEnv *jniEnv = jaw_util_get_jni_env();
+	jobject jhyperlink = (*jniEnv)->NewGlobalRef(jniEnv, jaw_hyperlink->jhyperlink);
+	if (!jhyperlink) {
+		return 0;
+	}
+
 	jclass classAtkHyperlink = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkHyperlink");
 	jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkHyperlink, "get_start_index", "()I");
 	jint jindex = (*jniEnv)->CallIntMethod(jniEnv, jhyperlink, jmid);
+	(*jniEnv)->DeleteGlobalRef(jniEnv, jhyperlink);
 
 	return jindex;
 }
@@ -166,12 +182,16 @@ static gint jaw_hyperlink_get_start_inde
 static gboolean jaw_hyperlink_is_valid (AtkHyperlink *atk_hyperlink)
 {
 	JawHyperlink *jaw_hyperlink = JAW_HYPERLINK(atk_hyperlink);
-	jobject jhyperlink = jaw_hyperlink->jhyperlink;
-
 	JNIEnv *jniEnv = jaw_util_get_jni_env();
+	jobject jhyperlink = (*jniEnv)->NewGlobalRef(jniEnv, jaw_hyperlink->jhyperlink);
+	if (!jhyperlink) {
+		return FALSE;
+	}
+
 	jclass classAtkHyperlink = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkHyperlink");
 	jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkHyperlink, "is_valid", "()Z");
 	jboolean jvalid = (*jniEnv)->CallBooleanMethod(jniEnv, jhyperlink, jmid);
+	(*jniEnv)->DeleteGlobalRef(jniEnv, jhyperlink);
 
 	return jvalid;
 }
@@ -179,12 +199,16 @@ static gboolean jaw_hyperlink_is_valid (
 static gint jaw_hyperlink_get_n_anchors (AtkHyperlink *atk_hyperlink)
 {
 	JawHyperlink *jaw_hyperlink = JAW_HYPERLINK(atk_hyperlink);
-	jobject jhyperlink = jaw_hyperlink->jhyperlink;
-
 	JNIEnv *jniEnv = jaw_util_get_jni_env();
+	jobject jhyperlink = (*jniEnv)->NewGlobalRef(jniEnv, jaw_hyperlink->jhyperlink);
+	if (!jhyperlink) {
+		return 0;
+	}
+
 	jclass classAtkHyperlink = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkHyperlink");
 	jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkHyperlink, "get_n_anchors", "()I");
 	jint janchors = (*jniEnv)->CallIntMethod(jniEnv, jhyperlink, jmid);
+	(*jniEnv)->DeleteGlobalRef(jniEnv, jhyperlink);
 
 	return janchors;
 }
--- a/jni/src/jawhypertext.c
+++ b/jni/src/jawhypertext.c
@@ -63,7 +63,7 @@ jaw_hypertext_data_init (jobject ac)
 	jclass classHypertext = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkHypertext");
 	jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classHypertext, "<init>", "(Ljavax/accessibility/AccessibleContext;)V");
 	jobject jatk_hypertext = (*jniEnv)->NewObject(jniEnv, classHypertext, jmid, ac);
-	data->atk_hypertext = (*jniEnv)->NewGlobalRef(jniEnv, jatk_hypertext);
+	data->atk_hypertext = (*jniEnv)->NewWeakGlobalRef(jniEnv, jatk_hypertext);
 
 	data->link_table = g_hash_table_new_full(NULL, NULL, NULL, link_destroy_notify);
 
@@ -79,7 +79,7 @@ jaw_hypertext_data_finalize (gpointer p)
 	if (data && data->atk_hypertext) {
 		g_hash_table_remove_all(data->link_table);
 
-		(*jniEnv)->DeleteGlobalRef(jniEnv, data->atk_hypertext);
+		(*jniEnv)->DeleteWeakGlobalRef(jniEnv, data->atk_hypertext);
 		data->atk_hypertext = NULL;
 	}
 }
@@ -89,12 +89,16 @@ jaw_hypertext_get_link (AtkHypertext *hy
 {
 	JawObject *jaw_obj = JAW_OBJECT(hypertext);
 	HypertextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_HYPERTEXT);
-	jobject atk_hypertext = data->atk_hypertext;
-	
 	JNIEnv *jniEnv = jaw_util_get_jni_env();
+	jobject atk_hypertext = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_hypertext);
+	if (!atk_hypertext) {
+		return NULL;
+	}
+
 	jclass classAtkHypertext = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkHypertext");
 	jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkHypertext, "get_link", "(I)Lorg/GNOME/Accessibility/AtkHyperlink;");
 	jobject jhyperlink = (*jniEnv)->CallObjectMethod(jniEnv, atk_hypertext, jmid, (jint)link_index);
+	(*jniEnv)->DeleteGlobalRef(jniEnv, atk_hypertext);
 
 	if (!jhyperlink) {
 		return NULL;
@@ -111,13 +115,18 @@ jaw_hypertext_get_n_links (AtkHypertext
 {
 	JawObject *jaw_obj = JAW_OBJECT(hypertext);
 	HypertextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_HYPERTEXT);
-	jobject atk_hypertext = data->atk_hypertext;
-	
 	JNIEnv *jniEnv = jaw_util_get_jni_env();
+	jobject atk_hypertext = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_hypertext);
+	if (!atk_hypertext) {
+		return 0;
+	}
+
 	jclass classAtkHypertext = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkHypertext");
 	jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkHypertext, "get_n_links", "()I");
 	
-	return (gint)(*jniEnv)->CallIntMethod(jniEnv, atk_hypertext, jmid);
+	gint ret = (gint)(*jniEnv)->CallIntMethod(jniEnv, atk_hypertext, jmid);
+	(*jniEnv)->DeleteGlobalRef(jniEnv, atk_hypertext);
+	return ret;
 }
 
 static gint
@@ -125,12 +134,17 @@ jaw_hypertext_get_link_index (AtkHyperte
 {
 	JawObject *jaw_obj = JAW_OBJECT(hypertext);
 	HypertextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_HYPERTEXT);
-	jobject atk_hypertext = data->atk_hypertext;
-	
 	JNIEnv *jniEnv = jaw_util_get_jni_env();
+	jobject atk_hypertext = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_hypertext);
+	if (!atk_hypertext) {
+		return 0;
+	}
+
 	jclass classAtkHypertext = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkHypertext");
 	jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkHypertext, "get_link_index", "(I)I");
 	
-	return (gint)(*jniEnv)->CallIntMethod(jniEnv, atk_hypertext, jmid, (jint)char_index);
+	gint ret = (gint)(*jniEnv)->CallIntMethod(jniEnv, atk_hypertext, jmid, (jint)char_index);
+	(*jniEnv)->DeleteGlobalRef(jniEnv, atk_hypertext);
+	return ret;
 }
 
--- a/jni/src/jawimage.c
+++ b/jni/src/jawimage.c
@@ -59,7 +59,7 @@ jaw_image_data_init (jobject ac)
 	jclass classImage = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkImage");
 	jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classImage, "<init>", "(Ljavax/accessibility/AccessibleContext;)V");
 	jobject jatk_image = (*jniEnv)->NewObject(jniEnv, classImage, jmid, ac);
-	data->atk_image = (*jniEnv)->NewGlobalRef(jniEnv, jatk_image);
+	data->atk_image = (*jniEnv)->NewWeakGlobalRef(jniEnv, jatk_image);
 
 	return data;
 }
@@ -79,7 +79,7 @@ jaw_image_data_finalize (gpointer p)
 		}
 
 
-		(*jniEnv)->DeleteGlobalRef(jniEnv, data->atk_image);
+		(*jniEnv)->DeleteWeakGlobalRef(jniEnv, data->atk_image);
 		data->atk_image = NULL;
 	}
 }
@@ -90,12 +90,16 @@ jaw_image_get_image_position (AtkImage *
 {
 	JawObject *jaw_obj = JAW_OBJECT(image);
 	ImageData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_IMAGE);
-	jobject atk_image = data->atk_image;
-
 	JNIEnv *jniEnv = jaw_util_get_jni_env();
+	jobject atk_image = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_image);
+	if (!atk_image) {
+		return;
+	}
+
 	jclass classAtkImage = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkImage");
 	jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkImage, "get_image_position", "(I)Ljava/awt/Point;");
 	jobject jpoint = (*jniEnv)->CallObjectMethod(jniEnv, atk_image, jmid, (jint)coord_type);
+	(*jniEnv)->DeleteGlobalRef(jniEnv, atk_image);
 	
 	if (jpoint == NULL) {
 		(*x) = 0;
@@ -118,12 +122,16 @@ jaw_image_get_image_description (AtkImag
 {
 	JawObject *jaw_obj = JAW_OBJECT(image);
 	ImageData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_IMAGE);
-	jobject atk_image = data->atk_image;
-
 	JNIEnv *jniEnv = jaw_util_get_jni_env();
+	jobject atk_image = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_image);
+	if (!atk_image) {
+		return NULL;
+	}
+
 	jclass classAtkImage = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkImage");
 	jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkImage, "get_image_description", "()Ljava/lang/String;");
 	jstring jstr = (*jniEnv)->CallObjectMethod(jniEnv, atk_image, jmid);
+	(*jniEnv)->DeleteGlobalRef(jniEnv, atk_image);
 	
 	if (data->image_description != NULL) {
 		(*jniEnv)->ReleaseStringUTFChars(jniEnv, data->jstrImageDescription, data->image_description);
@@ -141,12 +149,16 @@ jaw_image_get_image_size (AtkImage *imag
 {
 	JawObject *jaw_obj = JAW_OBJECT(image);
 	ImageData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_IMAGE);
-	jobject atk_image = data->atk_image;
-
 	JNIEnv *jniEnv = jaw_util_get_jni_env();
+	jobject atk_image = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_image);
+	if (!atk_image) {
+		return;
+	}
+
 	jclass classAtkImage = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkImage");
 	jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkImage, "get_image_size", "()Ljava/awt/Dimension;");
 	jobject jdimension = (*jniEnv)->CallObjectMethod(jniEnv, atk_image, jmid);
+	(*jniEnv)->DeleteGlobalRef(jniEnv, atk_image);
 
 	if (jdimension == NULL) {
 		(*width) = 0;
--- a/jni/src/jawselection.c
+++ b/jni/src/jawselection.c
@@ -63,7 +63,7 @@ jaw_selection_data_init (jobject ac)
 	jclass classSelection = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkSelection");
 	jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classSelection, "<init>", "(Ljavax/accessibility/AccessibleContext;)V");
 	jobject jatk_selection = (*jniEnv)->NewObject(jniEnv, classSelection, jmid, ac);
-	data->atk_selection = (*jniEnv)->NewGlobalRef(jniEnv, jatk_selection);
+	data->atk_selection = (*jniEnv)->NewWeakGlobalRef(jniEnv, jatk_selection);
 
 	return data;
 }
@@ -75,7 +75,7 @@ jaw_selection_data_finalize (gpointer p)
 	JNIEnv *jniEnv = jaw_util_get_jni_env();
 
 	if (data && data->atk_selection) {
-		(*jniEnv)->DeleteGlobalRef(jniEnv, data->atk_selection);
+		(*jniEnv)->DeleteWeakGlobalRef(jniEnv, data->atk_selection);
 		data->atk_selection = NULL;
 	}
 }
@@ -85,12 +85,16 @@ jaw_selection_add_selection (AtkSelectio
 {
 	JawObject *jaw_obj = JAW_OBJECT(selection);
 	SelectionData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_SELECTION);
-	jobject atk_selection = data->atk_selection;
-
 	JNIEnv *jniEnv = jaw_util_get_jni_env();
+	jobject atk_selection = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_selection);
+	if (!atk_selection) {
+		return FALSE;
+	}
+
 	jclass classAtkSelection = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkSelection");
 	jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkSelection, "add_selection", "(I)Z");
 	jboolean jbool = (*jniEnv)->CallBooleanMethod(jniEnv, atk_selection, jmid, (jint)i);
+	(*jniEnv)->DeleteGlobalRef(jniEnv, atk_selection);
 
 	if (jbool == JNI_TRUE) {
 		return TRUE;
@@ -104,12 +108,16 @@ jaw_selection_clear_selection (AtkSelect
 {
 	JawObject *jaw_obj = JAW_OBJECT(selection);
 	SelectionData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_SELECTION);
-	jobject atk_selection = data->atk_selection;
-
 	JNIEnv *jniEnv = jaw_util_get_jni_env();
+	jobject atk_selection = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_selection);
+	if (!atk_selection) {
+		return FALSE;
+	}
+
 	jclass classAtkSelection = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkSelection");
 	jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkSelection, "clear_selection", "()Z");
 	jboolean jbool = (*jniEnv)->CallBooleanMethod(jniEnv, atk_selection, jmid);
+	(*jniEnv)->DeleteGlobalRef(jniEnv, atk_selection);
 
 	if (jbool == JNI_TRUE) {
 		return TRUE;
@@ -123,12 +131,16 @@ jaw_selection_ref_selection (AtkSelectio
 {
 	JawObject *jaw_obj = JAW_OBJECT(selection);
 	SelectionData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_SELECTION);
-	jobject atk_selection = data->atk_selection;
-
 	JNIEnv *jniEnv = jaw_util_get_jni_env();
+	jobject atk_selection = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_selection);
+	if (!atk_selection) {
+		return NULL;
+	}
+
 	jclass classAtkSelection = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkSelection");
 	jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkSelection, "ref_selection", "(I)Ljavax/accessibility/Accessible;");
 	jobject jchild = (*jniEnv)->CallObjectMethod(jniEnv, atk_selection, jmid, (jint)i);
+	(*jniEnv)->DeleteGlobalRef(jniEnv, atk_selection);
 
 	if (!jchild) {
 		return NULL;
@@ -149,12 +161,16 @@ jaw_selection_get_selection_count (AtkSe
 {
 	JawObject *jaw_obj = JAW_OBJECT(selection);
 	SelectionData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_SELECTION);
-	jobject atk_selection = data->atk_selection;
-
 	JNIEnv *jniEnv = jaw_util_get_jni_env();
+	jobject atk_selection = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_selection);
+	if (!atk_selection) {
+		return 0;
+	}
+
 	jclass classAtkSelection = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkSelection");
 	jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkSelection, "get_selection_count", "()I");
 	jint jcount = (*jniEnv)->CallIntMethod(jniEnv, atk_selection, jmid);
+	(*jniEnv)->DeleteGlobalRef(jniEnv, atk_selection);
 
 	return (gint)jcount;
 }
@@ -164,12 +180,16 @@ jaw_selection_is_child_selected (AtkSele
 {
 	JawObject *jaw_obj = JAW_OBJECT(selection);
 	SelectionData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_SELECTION);
-	jobject atk_selection = data->atk_selection;
-
 	JNIEnv *jniEnv = jaw_util_get_jni_env();
+	jobject atk_selection = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_selection);
+	if (!atk_selection) {
+		return FALSE;
+	}
+
 	jclass classAtkSelection = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkSelection");
 	jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkSelection, "is_child_selected", "(I)Z");
 	jboolean jbool = (*jniEnv)->CallBooleanMethod(jniEnv, atk_selection, jmid, (jint)i);
+	(*jniEnv)->DeleteGlobalRef(jniEnv, atk_selection);
 
 	if (jbool == JNI_TRUE) {
 		return TRUE;
@@ -183,12 +203,16 @@ jaw_selection_remove_selection (AtkSelec
 {
 	JawObject *jaw_obj = JAW_OBJECT(selection);
 	SelectionData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_SELECTION);
-	jobject atk_selection = data->atk_selection;
-
 	JNIEnv *jniEnv = jaw_util_get_jni_env();
+	jobject atk_selection = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_selection);
+	if (!atk_selection) {
+		return FALSE;
+	}
+
 	jclass classAtkSelection = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkSelection");
 	jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkSelection, "remove_selection", "(I)Z");
 	jboolean jbool = (*jniEnv)->CallBooleanMethod(jniEnv, atk_selection, jmid, (jint)i);
+	(*jniEnv)->DeleteGlobalRef(jniEnv, atk_selection);
 
 	if (jbool == JNI_TRUE) {
 		return TRUE;
@@ -202,12 +226,16 @@ jaw_selection_select_all_selection (AtkS
 {
 	JawObject *jaw_obj = JAW_OBJECT(selection);
 	SelectionData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_SELECTION);
-	jobject atk_selection = data->atk_selection;
-
 	JNIEnv *jniEnv = jaw_util_get_jni_env();
+	jobject atk_selection = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_selection);
+	if (!atk_selection) {
+		return FALSE;
+	}
+
 	jclass classAtkSelection = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkSelection");
 	jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkSelection, "select_all_selection", "()Z");
 	jboolean jbool = (*jniEnv)->CallBooleanMethod(jniEnv, atk_selection, jmid);
+	(*jniEnv)->DeleteGlobalRef(jniEnv, atk_selection);
 
 	if (jbool == JNI_TRUE) {
 		return TRUE;
--- a/jni/src/jawtable.c
+++ b/jni/src/jawtable.c
@@ -108,7 +108,7 @@ jaw_table_data_init (jobject ac)
                                        "(Ljavax/accessibility/AccessibleContext;)V");
 
   jobject jatk_table = (*env)->NewObject(env, classTable, jmid, ac);
-  data->atk_table = (*env)->NewGlobalRef(env, jatk_table);
+  data->atk_table = (*env)->NewWeakGlobalRef(env, jatk_table);
 
   return data;
 }
@@ -129,7 +129,7 @@ jaw_table_data_finalize (gpointer p)
       data->description = NULL;
     }
 
-    (*env)->DeleteGlobalRef(env, data->atk_table);
+    (*env)->DeleteWeakGlobalRef(env, data->atk_table);
     data->atk_table = NULL;
   }
 }
@@ -139,15 +139,19 @@ jaw_table_ref_at (AtkTable *table, gint
 {
   JawObject *jaw_obj = JAW_OBJECT(table);
   TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE);
-  jobject atk_table = data->atk_table;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table);
+  if (!atk_table) {
+    return NULL;
+  }
+
   jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable");
   jmethodID jmid = (*env)->GetMethodID(env,
                                        classAtkTable,
                                        "ref_at",
                                        "(II)Ljavax/accessibility/AccessibleContext;");
   jobject jac = (*env)->CallObjectMethod(env, atk_table, jmid, (jint)row, (jint)column);
+  (*env)->DeleteGlobalRef(env, atk_table);
 
   if (!jac)
     return NULL;
@@ -165,12 +169,16 @@ jaw_table_get_column_at_index (AtkTable
 {
   JawObject *jaw_obj = JAW_OBJECT(table);
   TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE);
-  jobject atk_table = data->atk_table;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table);
+  if (!atk_table) {
+    return 0;
+  }
+
   jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable");
   jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "get_column_at_index", "(I)I");
   jint jcolumn = (*env)->CallIntMethod(env, atk_table, jmid, (jint)index);
+  (*env)->DeleteGlobalRef(env, atk_table);
 
   return (gint)jcolumn;
 }
@@ -180,12 +188,16 @@ jaw_table_get_row_at_index (AtkTable *ta
 {
   JawObject *jaw_obj = JAW_OBJECT(table);
   TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE);
-  jobject atk_table = data->atk_table;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table);
+  if (!atk_table) {
+    return 0;
+  }
+
   jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable");
   jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "get_row_at_index", "(I)I");
   jint jrow = (*env)->CallIntMethod(env, atk_table, jmid, (jint)index);
+  (*env)->DeleteGlobalRef(env, atk_table);
 
   return (gint)jrow;
 }
@@ -195,12 +207,16 @@ jaw_table_get_n_columns	(AtkTable *table
 {
   JawObject *jaw_obj = JAW_OBJECT(table);
   TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE);
-  jobject atk_table = data->atk_table;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table);
+  if (!atk_table) {
+    return 0;
+  }
+
   jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable");
   jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "get_n_columns", "()I");
   jint jcolumns = (*env)->CallIntMethod(env, atk_table, jmid);
+  (*env)->DeleteGlobalRef(env, atk_table);
 
   return (gint)jcolumns;
 }
@@ -210,12 +226,16 @@ jaw_table_get_n_rows (AtkTable *table)
 {
   JawObject *jaw_obj = JAW_OBJECT(table);
   TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE);
-  jobject atk_table = data->atk_table;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table);
+  if (!atk_table) {
+    return 0;
+  }
+
   jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable");
   jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "get_n_rows", "()I");
   jint jrows = (*env)->CallIntMethod(env, atk_table, jmid);
+  (*env)->DeleteGlobalRef(env, atk_table);
 
   return (gint)jrows;
 }
@@ -225,12 +245,16 @@ jaw_table_get_column_extent_at (AtkTable
 {
   JawObject *jaw_obj = JAW_OBJECT(table);
   TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE);
-  jobject atk_table = data->atk_table;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table);
+  if (!atk_table) {
+    return 0;
+  }
+
   jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable");
   jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "get_column_extent_at", "(II)I");
   jint jextent = (*env)->CallIntMethod(env, atk_table, jmid, (jint)row, (jint)column);
+  (*env)->DeleteGlobalRef(env, atk_table);
 
   return (gint)jextent;
 }
@@ -240,12 +264,16 @@ jaw_table_get_row_extent_at (AtkTable *t
 {
   JawObject *jaw_obj = JAW_OBJECT(table);
   TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE);
-  jobject atk_table = data->atk_table;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table);
+  if (!atk_table) {
+    return 0;
+  }
+
   jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable");
   jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "get_row_extent_at", "(II)I");
   jint jextent = (*env)->CallIntMethod(env, atk_table, jmid, (jint)row, (jint)column);
+  (*env)->DeleteGlobalRef(env, atk_table);
 
   return (gint)jextent;
 }
@@ -255,9 +283,12 @@ jaw_table_get_caption (AtkTable	*table)
 {
   JawObject *jaw_obj = JAW_OBJECT(table);
   TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE);
-  jobject atk_table = data->atk_table;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table);
+  if (!atk_table) {
+    return NULL;
+  }
+
   jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable");
   jmethodID jmid = (*env)->GetMethodID(env,
                                        classAtkTable,
@@ -265,6 +296,7 @@ jaw_table_get_caption (AtkTable	*table)
                                        "()Ljavax/accessibility/AccessibleContext;");
 
   jobject jac = (*env)->CallObjectMethod(env, atk_table, jmid);
+  (*env)->DeleteGlobalRef(env, atk_table);
 
   if (!jac)
     return NULL;
@@ -279,12 +311,16 @@ jaw_table_get_column_description (AtkTab
 {
   JawObject *jaw_obj = JAW_OBJECT(table);
   TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE);
-  jobject atk_table = data->atk_table;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table);
+  if (!atk_table) {
+    return NULL;
+  }
+
   jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable");
   jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "get_column_description", "(I)Ljava/lang/String;");
   jstring jstr = (*env)->CallObjectMethod(env, atk_table, jmid, (jint)column);
+  (*env)->DeleteGlobalRef(env, atk_table);
 
   if (data->description != NULL)
   {
@@ -303,12 +339,16 @@ jaw_table_get_row_description (AtkTable
 {
   JawObject *jaw_obj = JAW_OBJECT(table);
   TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE);
-  jobject atk_table = data->atk_table;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table);
+  if (!atk_table) {
+    return NULL;
+  }
+
   jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable");
   jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "get_row_description", "(I)Ljava/lang/String;");
   jstring jstr = (*env)->CallObjectMethod(env, atk_table, jmid, (jint)row);
+  (*env)->DeleteGlobalRef(env, atk_table);
 
   if (data->description != NULL)
   {
@@ -327,12 +367,16 @@ jaw_table_get_column_header (AtkTable *t
 {
   JawObject *jaw_obj = JAW_OBJECT(table);
   TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE);
-  jobject atk_table = data->atk_table;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table);
+  if (!atk_table) {
+    return NULL;
+  }
+
   jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable");
   jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "get_column_header", "(I)Ljavax/accessibility/AccessibleContext;");
   jobject jac = (*env)->CallObjectMethod(env, atk_table, jmid, (jint)column);
+  (*env)->DeleteGlobalRef(env, atk_table);
 
   if (!jac)
     return NULL;
@@ -347,12 +391,16 @@ jaw_table_get_row_header (AtkTable *tabl
 {
   JawObject *jaw_obj = JAW_OBJECT(table);
   TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE);
-  jobject atk_table = data->atk_table;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table);
+  if (!atk_table) {
+    return NULL;
+  }
+
   jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable");
   jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "get_row_header", "(I)Ljavax/accessibility/AccessibleContext;");
   jobject jac = (*env)->CallObjectMethod(env, atk_table, jmid, (jint)row);
+  (*env)->DeleteGlobalRef(env, atk_table);
 
   if (!jac)
     return NULL;
@@ -367,12 +415,16 @@ jaw_table_get_summary (AtkTable *table)
 {
   JawObject *jaw_obj = JAW_OBJECT(table);
   TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE);
-  jobject atk_table = data->atk_table;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table);
+  if (!atk_table) {
+    return NULL;
+  }
+
   jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable");
   jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "get_summary", "()Ljavax/accessibility/AccessibleContext;");
   jobject jac = (*env)->CallObjectMethod(env, atk_table, jmid);
+  (*env)->DeleteGlobalRef(env, atk_table);
 
   if (!jac)
     return NULL;
@@ -387,12 +439,16 @@ jaw_table_get_selected_columns (AtkTable
 {
   JawObject *jaw_obj = JAW_OBJECT(table);
   TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE);
-  jobject atk_table = data->atk_table;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table);
+  if (!atk_table) {
+    return 0;
+  }
+
   jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable");
   jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "get_selected_columns", "()[I");
   jintArray jcolumnArray = (*env)->CallObjectMethod(env, atk_table, jmid);
+  (*env)->DeleteGlobalRef(env, atk_table);
 
   if (!jcolumnArray)
     return 0;
@@ -416,12 +472,16 @@ jaw_table_get_selected_rows (AtkTable *t
 {
   JawObject *jaw_obj = JAW_OBJECT(table);
   TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE);
-  jobject atk_table = data->atk_table;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table);
+  if (!atk_table) {
+    return 0;
+  }
+
   jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable");
   jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "get_selected_rows", "()[I");
   jintArray jrowArray = (*env)->CallObjectMethod(env, atk_table, jmid);
+  (*env)->DeleteGlobalRef(env, atk_table);
 
   if (!jrowArray)
     return 0;
@@ -445,12 +505,16 @@ jaw_table_is_column_selected (AtkTable *
 {
   JawObject *jaw_obj = JAW_OBJECT(table);
   TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE);
-  jobject atk_table = data->atk_table;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table);
+  if (!atk_table) {
+    return FALSE;
+  }
+
   jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable");
   jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "is_column_selected", "(I)Z");
   jboolean jselected = (*env)->CallBooleanMethod(env, atk_table, jmid, (jint)column);
+  (*env)->DeleteGlobalRef(env, atk_table);
 
   if (jselected == JNI_TRUE)
     return TRUE;
@@ -463,12 +527,16 @@ jaw_table_is_row_selected (AtkTable *tab
 {
   JawObject *jaw_obj = JAW_OBJECT(table);
   TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE);
-  jobject atk_table = data->atk_table;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table);
+  if (!atk_table) {
+    return FALSE;
+  }
+
   jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable");
   jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "is_row_selected", "(I)Z");
   jboolean jselected = (*env)->CallBooleanMethod(env, atk_table, jmid, (jint)row);
+  (*env)->DeleteGlobalRef(env, atk_table);
 
   if (jselected == JNI_TRUE)
     return TRUE;
@@ -481,12 +549,16 @@ jaw_table_is_selected (AtkTable *table,
 {
   JawObject *jaw_obj = JAW_OBJECT(table);
   TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE);
-  jobject atk_table = data->atk_table;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table);
+  if (!atk_table) {
+    return FALSE;
+  }
+
   jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable");
   jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "is_selected", "(II)Z");
   jboolean jselected = (*env)->CallBooleanMethod(env, atk_table, jmid, (jint)row, (jint)column);
+  (*env)->DeleteGlobalRef(env, atk_table);
 
   if (jselected == JNI_TRUE)
     return TRUE;
@@ -499,12 +571,16 @@ jaw_table_add_row_selection(AtkTable *ta
 {
   JawObject *jaw_obj = JAW_OBJECT(table);
   TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE);
-  jobject atk_table = data->atk_table;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table);
+  if (!atk_table) {
+    return FALSE;
+  }
+
   jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable");
   jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "addRowSelection", "(I)Z");
   jboolean jselected = (*env)->CallBooleanMethod(env, atk_table, jmid, (jint)row);
+  (*env)->DeleteGlobalRef(env, atk_table);
 
   if (jselected == JNI_TRUE)
     return TRUE;
@@ -517,12 +593,16 @@ jaw_table_add_column_selection(AtkTable
 {
   JawObject *jaw_obj = JAW_OBJECT(table);
   TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE);
-  jobject atk_table = data->atk_table;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table);
+  if (!atk_table) {
+    return FALSE;
+  }
+
   jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable");
   jmethodID jmid = (*env)->GetMethodID(env, classAtkTable, "addColumnSelection", "(I)Z");
   jboolean jselected = (*env)->CallBooleanMethod(env, atk_table, jmid, (jint)column);
+  (*env)->DeleteGlobalRef(env, atk_table);
 
   if (jselected == JNI_TRUE)
     return TRUE;
@@ -535,9 +615,12 @@ jaw_table_set_row_description(AtkTable *
 {
   JawObject *jaw_obj = JAW_OBJECT(table);
   TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE);
-  jobject atk_table = data->atk_table;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table);
+  if (!atk_table) {
+    return;
+  }
+
   jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable");
   jmethodID jmid = (*env)->GetMethodID(env,
                                        classAtkTable,
@@ -545,6 +628,7 @@ jaw_table_set_row_description(AtkTable *
                                        "(ILjava/lang/String;)V");
   jstring jstr = (*env)->NewStringUTF(env, description);
   (*env)->CallVoidMethod(env, atk_table, jmid, (jint)row, jstr);
+  (*env)->DeleteGlobalRef(env, atk_table);
 }
 
 static void
@@ -552,9 +636,12 @@ jaw_table_set_column_description(AtkTabl
 {
   JawObject *jaw_obj = JAW_OBJECT(table);
   TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE);
-  jobject atk_table = data->atk_table;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table);
+  if (!atk_table) {
+    return;
+  }
+
   jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable");
   jmethodID jmid = (*env)->GetMethodID(env,
                                        classAtkTable,
@@ -562,6 +649,7 @@ jaw_table_set_column_description(AtkTabl
                                        "(ILjava/lang/String;)V");
   jstring jstr = (*env)->NewStringUTF(env, description);
   (*env)->CallVoidMethod(env, atk_table, jmid, (jint)column, jstr);
+  (*env)->DeleteGlobalRef(env, atk_table);
 }
 
 static void
@@ -569,15 +657,19 @@ jaw_table_set_row_header(AtkTable *table
 {
   JawObject *jaw_obj = JAW_OBJECT(table);
   TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE);
-  jobject atk_table = data->atk_table;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table);
+  if (!atk_table) {
+    return;
+  }
+
   jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable");
   jmethodID jmid = (*env)->GetMethodID(env,
                                        classAtkTable,
                                        "setRowHeader",
                                        "(ILjavax/accessibility/AccessibleTable;)V");
   (*env)->CallVoidMethod(env, atk_table, jmid, (jint)row, (jobject)header);
+  (*env)->DeleteGlobalRef(env, atk_table);
 }
 
 static void
@@ -585,15 +677,19 @@ jaw_table_set_column_header(AtkTable *ta
 {
   JawObject *jaw_obj = JAW_OBJECT(table);
   TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE);
-  jobject atk_table = data->atk_table;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table);
+  if (!atk_table) {
+    return;
+  }
+
   jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable");
   jmethodID jmid = (*env)->GetMethodID(env,
                                        classAtkTable,
                                        "setColumnHeader",
                                        "(ILjavax/accessibility/AccessibleTable;)V");
   (*env)->CallVoidMethod(env, atk_table, jmid, (jint)column, (jobject)header);
+  (*env)->DeleteGlobalRef(env, atk_table);
 }
 
 static void
@@ -601,15 +697,19 @@ jaw_table_set_caption(AtkTable *table, A
 {
   JawObject *jaw_obj = JAW_OBJECT(table);
   TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE);
-  jobject atk_table = data->atk_table;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table);
+  if (!atk_table) {
+    return;
+  }
+
   jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable");
   jmethodID jmid = (*env)->GetMethodID(env,
                                        classAtkTable,
                                        "setCaption",
                                        "(Ljavax/accessibility/Accessible;)V");
   (*env)->CallVoidMethod(env, atk_table, jmid, (jobject)caption);
+  (*env)->DeleteGlobalRef(env, atk_table);
 }
 
 static void
@@ -617,13 +717,17 @@ jaw_table_set_summary(AtkTable *table, A
 {
   JawObject *jaw_obj = JAW_OBJECT(table);
   TableData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE);
-  jobject atk_table = data->atk_table;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_table = (*env)->NewGlobalRef(env, data->atk_table);
+  if (!atk_table) {
+    return;
+  }
+
   jclass classAtkTable = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkTable");
   jmethodID jmid = (*env)->GetMethodID(env,
                                        classAtkTable,
                                        "setSummary",
                                        "(Ljavax/accessibility/Accessible;)V");
   (*env)->CallVoidMethod(env, atk_table, jmid, (jobject)summary);
+  (*env)->DeleteGlobalRef(env, atk_table);
 }
--- a/jni/src/jawtablecell.c
+++ b/jni/src/jawtablecell.c
@@ -61,7 +61,7 @@ jaw_table_cell_data_init (jobject ac)
   jclass classTableCell = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkTableCell");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classTableCell, "<init>", "(Ljavax/accessibility/AccessibleContext;)V");
   jobject jatk_table_cell = (*jniEnv)->NewObject(jniEnv, classTableCell, jmid, ac);
-  data->atk_table_cell = (*jniEnv)->NewGlobalRef(jniEnv, jatk_table_cell);
+  data->atk_table_cell = (*jniEnv)->NewWeakGlobalRef(jniEnv, jatk_table_cell);
 
   return data;
 }
@@ -82,7 +82,7 @@ jaw_table_cell_data_finalize (gpointer p
       data->description = NULL;
     }
 
-    (*jniEnv)->DeleteGlobalRef(jniEnv, data->atk_table_cell);
+    (*jniEnv)->DeleteWeakGlobalRef(jniEnv, data->atk_table_cell);
     data->atk_table_cell = NULL;
   }
 }
@@ -92,9 +92,12 @@ jaw_table_cell_get_table(AtkTableCell *c
 {
   JawObject *jaw_obj = JAW_OBJECT(cell);
   TableCellData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE_CELL);
-  jobject jatk_table_cell = data->atk_table_cell;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject jatk_table_cell = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_table_cell);
+  if (!jatk_table_cell) {
+    return NULL;
+  }
+
   jclass classAtkTableCell = (*jniEnv)->FindClass(jniEnv,
                                                   "org/GNOME/Accessibility/AtkTableCell");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -102,6 +105,7 @@ jaw_table_cell_get_table(AtkTableCell *c
                                           "getTable",
                                           "()Ljavax/accessibility/AccessibleTable;");
   jobject jac = (*jniEnv)->CallObjectMethod(jniEnv, jatk_table_cell, jmid);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, jatk_table_cell);
 
   if (!jac)
     return NULL;
@@ -116,9 +120,12 @@ jaw_table_cell_get_position(AtkTableCell
 {
   JawObject *jaw_obj = JAW_OBJECT(cell);
   TableCellData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE_CELL);
-  jobject jatk_table_cell = data->atk_table_cell;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject jatk_table_cell = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_table_cell);
+  if (!jatk_table_cell) {
+    return FALSE;
+  }
+
   jclass classAtkTableCell = (*jniEnv)->FindClass(jniEnv,
                                                   "org/GNOME/Accessibility/AtkTableCell");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -130,6 +137,7 @@ jaw_table_cell_get_position(AtkTableCell
                                                    jmid,
                                                    (jint)GPOINTER_TO_INT(row),
                                                    (jint)GPOINTER_TO_INT(column));
+  (*jniEnv)->DeleteGlobalRef(jniEnv, jatk_table_cell);
 
   if (jposition == JNI_TRUE)
     return TRUE;
@@ -145,9 +153,12 @@ static gboolean jaw_table_cell_get_row_c
 {
   JawObject *jaw_obj = JAW_OBJECT(cell);
   TableCellData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE_CELL);
-  jobject jatk_table_cell = data->atk_table_cell;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject jatk_table_cell = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_table_cell);
+  if (!jatk_table_cell) {
+    return FALSE;
+  }
+
   jclass classAtkTableCell = (*jniEnv)->FindClass(jniEnv,
                                                   "org/GNOME/Accessibility/AtkTableCell");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -162,6 +173,7 @@ static gboolean jaw_table_cell_get_row_c
                                                 (jint)GPOINTER_TO_INT(row_span),
                                                 (jint)GPOINTER_TO_INT(column_span)
                                                 );
+  (*jniEnv)->DeleteGlobalRef(jniEnv, jatk_table_cell);
   if (jspan == JNI_TRUE)
     return TRUE;
 
@@ -173,16 +185,21 @@ jaw_table_cell_get_row_span(AtkTableCell
 {
   JawObject *jaw_obj = JAW_OBJECT(cell);
   TableCellData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE_CELL);
-  jobject jatk_table_cell = data->atk_table_cell;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject jatk_table_cell = (*env)->NewGlobalRef(env, data->atk_table_cell);
+  if (!jatk_table_cell) {
+    return 0;
+  }
+
   jclass classAtkTableCell = (*env)->FindClass(env,
                                                "org/GNOME/Accessibility/AtkTableCell");
   jmethodID jmid = (*env)->GetMethodID(env,
                                        classAtkTableCell,
                                        "getRowSpan",
                                        "()I;");
-  return (gint) (*env)->CallIntMethod(env, jatk_table_cell, jmid);
+  gint ret = (gint) (*env)->CallIntMethod(env, jatk_table_cell, jmid);
+  (*env)->DeleteGlobalRef(env, jatk_table_cell);
+  return ret;
 }
 
 static gint
@@ -190,15 +207,20 @@ jaw_table_cell_get_column_span(AtkTableC
 {
   JawObject *jaw_obj = JAW_OBJECT(cell);
   TableCellData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TABLE_CELL);
-  jobject jatk_table_cell = data->atk_table_cell;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject jatk_table_cell = (*env)->NewGlobalRef(env, data->atk_table_cell);
+  if (!jatk_table_cell) {
+    return 0;
+  }
+
   jclass classAtkTableCell = (*env)->FindClass(env,
                                                "org/GNOME/Accessibility/AtkTableCell");
   jmethodID jmid = (*env)->GetMethodID(env,
                                        classAtkTableCell,
                                        "getColumnSpan",
                                        "()I;");
-  return (gint) (*env)->CallIntMethod(env, jatk_table_cell, jmid);
+  gint ret = (gint) (*env)->CallIntMethod(env, jatk_table_cell, jmid);
+  (*env)->DeleteGlobalRef(env, jatk_table_cell);
+  return ret;
 }
 
--- a/jni/src/jawtext.c
+++ b/jni/src/jawtext.c
@@ -118,7 +118,7 @@ jaw_text_data_init (jobject ac)
                                           "<init>",
                                           "(Ljavax/accessibility/AccessibleContext;)V");
   jobject jatk_text = (*jniEnv)->NewObject(jniEnv, classText, jmid, ac);
-  data->atk_text = (*jniEnv)->NewGlobalRef(jniEnv, jatk_text);
+  data->atk_text = (*jniEnv)->NewWeakGlobalRef(jniEnv, jatk_text);
 
   return data;
 }
@@ -139,7 +139,7 @@ jaw_text_data_finalize (gpointer p)
       data->text = NULL;
     }
 
-    (*jniEnv)->DeleteGlobalRef(jniEnv, data->atk_text);
+    (*jniEnv)->DeleteWeakGlobalRef(jniEnv, data->atk_text);
     data->atk_text = NULL;
   }
 }
@@ -164,9 +164,12 @@ jaw_text_get_text (AtkText *text, gint s
 {
   JawObject *jaw_obj = JAW_OBJECT(text);
   TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT);
-  jobject atk_text = data->atk_text;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text);
+  if (!atk_text) {
+    return NULL;
+  }
+
   jclass classAtkText = (*jniEnv)->FindClass(jniEnv,
                                              "org/GNOME/Accessibility/AtkText");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -179,6 +182,7 @@ jaw_text_get_text (AtkText *text, gint s
                                              jmid,
                                              (jint)start_offset,
                                              (jint)end_offset );
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text);
 
   return jaw_text_get_gtext_from_jstr(jniEnv, data, jstr);
 }
@@ -188,9 +192,12 @@ jaw_text_get_character_at_offset (AtkTex
 {
   JawObject *jaw_obj = JAW_OBJECT(text);
   TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT);
-  jobject atk_text = data->atk_text;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text);
+  if (!atk_text) {
+    return 0;
+  }
+
   jclass classAtkText = (*jniEnv)->FindClass(jniEnv,
                                              "org/GNOME/Accessibility/AtkText");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -200,6 +207,7 @@ jaw_text_get_character_at_offset (AtkTex
                                                atk_text,
                                                jmid,
                                                (jint)offset );
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text);
 
   return (gunichar)jcharacter;
 }
@@ -212,9 +220,12 @@ jaw_text_get_text_at_offset (AtkText *te
 {
   JawObject *jaw_obj = JAW_OBJECT(text);
   TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT);
-  jobject atk_text = data->atk_text;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text);
+  if (!atk_text) {
+    return NULL;
+  }
+
   jclass classAtkText = (*jniEnv)->FindClass(jniEnv,
                                              "org/GNOME/Accessibility/AtkText");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -226,6 +237,7 @@ jaw_text_get_text_at_offset (AtkText *te
                                                 jmid,
                                                 (jint)offset,
                                                 (jint)boundary_type );
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text);
 
   if (jStrSeq == NULL)
   {
@@ -262,9 +274,12 @@ jaw_text_get_caret_offset (AtkText *text
 {
   JawObject *jaw_obj = JAW_OBJECT(text);
   TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT);
-  jobject atk_text = data->atk_text;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text);
+  if (!atk_text) {
+    return 0;
+  }
+
   jclass classAtkText = (*jniEnv)->FindClass(jniEnv,
                                              "org/GNOME/Accessibility/AtkText");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -272,6 +287,7 @@ jaw_text_get_caret_offset (AtkText *text
                                           "get_caret_offset",
                                           "()I");
   jint joffset = (*jniEnv)->CallIntMethod(jniEnv, atk_text, jmid);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text);
 
   return (gint)joffset;
 }
@@ -284,9 +300,12 @@ jaw_text_get_character_extents (AtkText
 {
   JawObject *jaw_obj = JAW_OBJECT(text);
   TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT);
-  jobject atk_text = data->atk_text;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text);
+  if (!atk_text) {
+    return;
+  }
+
   jclass classAtkText = (*jniEnv)->FindClass(jniEnv,
                                              "org/GNOME/Accessibility/AtkText");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -298,6 +317,7 @@ jaw_text_get_character_extents (AtkText
                                               jmid,
                                               (jint)offset,
                                               (jint)coords);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text);
 
   if (jrect == NULL)
   {
@@ -312,9 +332,12 @@ jaw_text_get_character_count (AtkText *t
 {
   JawObject *jaw_obj = JAW_OBJECT(text);
   TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT);
-  jobject atk_text = data->atk_text;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text);
+  if (!atk_text) {
+    return 0;
+  }
+
   jclass classAtkText = (*jniEnv)->FindClass(jniEnv,
                                              "org/GNOME/Accessibility/AtkText");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -322,6 +345,7 @@ jaw_text_get_character_count (AtkText *t
                                           "get_character_count",
                                           "()I");
   jint jcount = (*jniEnv)->CallIntMethod(jniEnv, atk_text, jmid);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text);
 
   return (gint)jcount;
 }
@@ -331,9 +355,12 @@ jaw_text_get_offset_at_point (AtkText *t
 {
   JawObject *jaw_obj = JAW_OBJECT(text);
   TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT);
-  jobject atk_text = data->atk_text;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text);
+  if (!atk_text) {
+    return 0;
+  }
+
   jclass classAtkText = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkText");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
                                           classAtkText,
@@ -345,6 +372,7 @@ jaw_text_get_offset_at_point (AtkText *t
                                           (jint)x,
                                           (jint)y,
                                           (jint)coords);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text);
 
   return (gint)joffset;
 }
@@ -363,9 +391,12 @@ jaw_text_get_range_extents (AtkText *tex
 
   JawObject *jaw_obj = JAW_OBJECT(text);
   TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT);
-  jobject atk_text = data->atk_text;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text);
+  if (!atk_text) {
+    return;
+  }
+
   jclass classAtkText = (*jniEnv)->FindClass(jniEnv,
                                              "org/GNOME/Accessibility/AtkText");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -378,6 +409,7 @@ jaw_text_get_range_extents (AtkText *tex
                                               (jint)start_offset,
                                               (jint)end_offset,
                                               (jint)coord_type);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text);
 
   if (!jrect)
   {
@@ -392,9 +424,12 @@ jaw_text_get_n_selections (AtkText *text
 {
   JawObject *jaw_obj = JAW_OBJECT(text);
   TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT);
-  jobject atk_text = data->atk_text;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text);
+  if (!atk_text) {
+    return 0;
+  }
+
   jclass classAtkText = (*jniEnv)->FindClass(jniEnv,
                                              "org/GNOME/Accessibility/AtkText");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -402,6 +437,7 @@ jaw_text_get_n_selections (AtkText *text
                                           "get_n_selections",
                                           "()I");
   jint jselections = (*jniEnv)->CallIntMethod(jniEnv, atk_text, jmid);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text);
 
   return (gint)jselections;
 }
@@ -411,15 +447,19 @@ jaw_text_get_selection (AtkText *text, g
 {
   JawObject *jaw_obj = JAW_OBJECT(text);
   TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT);
-  jobject atk_text = data->atk_text;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text);
+  if (!atk_text) {
+    return NULL;
+  }
+
   jclass classAtkText = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkText");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
                                           classAtkText,
                                           "get_selection",
                                           "()Lorg/GNOME/Accessibility/AtkText$StringSequence;");
   jobject jStrSeq = (*jniEnv)->CallObjectMethod(jniEnv, atk_text, jmid);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text);
 
   if (jStrSeq == NULL)
   {
@@ -453,9 +493,12 @@ jaw_text_add_selection (AtkText *text, g
 {
   JawObject *jaw_obj = JAW_OBJECT(text);
   TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT);
-  jobject atk_text = data->atk_text;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text);
+  if (!atk_text) {
+    return FALSE;
+  }
+
   jclass classAtkText = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkText");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
                                          classAtkText,
@@ -466,6 +509,7 @@ jaw_text_add_selection (AtkText *text, g
                                                   jmid,
                                                   (jint)start_offset,
                                                   (jint)end_offset);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text);
 
   if (jresult == JNI_TRUE)
   {
@@ -480,9 +524,12 @@ jaw_text_remove_selection (AtkText *text
 {
   JawObject *jaw_obj = JAW_OBJECT(text);
   TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT);
-  jobject atk_text = data->atk_text;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text);
+  if (!atk_text) {
+    return FALSE;
+  }
+
   jclass classAtkText = (*jniEnv)->FindClass(jniEnv,
                                              "org/GNOME/Accessibility/AtkText");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -493,6 +540,7 @@ jaw_text_remove_selection (AtkText *text
                                                   atk_text,
                                                   jmid,
                                                   (jint)selection_num);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text);
 
   if (jresult == JNI_TRUE)
   {
@@ -507,9 +555,12 @@ jaw_text_set_selection (AtkText *text, g
 {
   JawObject *jaw_obj = JAW_OBJECT(text);
   TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT);
-  jobject atk_text = data->atk_text;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text);
+  if (!atk_text) {
+    return FALSE;
+  }
+
   jclass classAtkText = (*jniEnv)->FindClass(jniEnv, "org/GNOME/Accessibility/AtkText");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv, classAtkText, "set_selection", "(III)Z");
   jboolean jresult = (*jniEnv)->CallBooleanMethod(jniEnv,
@@ -518,6 +569,7 @@ jaw_text_set_selection (AtkText *text, g
                                                   (jint)selection_num,
                                                   (jint)start_offset,
                                                   (jint)end_offset);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text);
 
   if (jresult == JNI_TRUE) {
     return TRUE;
@@ -531,9 +583,12 @@ jaw_text_set_caret_offset (AtkText *text
 {
   JawObject *jaw_obj = JAW_OBJECT(text);
   TextData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_TEXT);
-  jobject atk_text = data->atk_text;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_text = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_text);
+  if (!atk_text) {
+    return FALSE;
+  }
+
   jclass classAtkText = (*jniEnv)->FindClass(jniEnv,
                                              "org/GNOME/Accessibility/AtkText");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -544,6 +599,7 @@ jaw_text_set_caret_offset (AtkText *text
                                                   atk_text,
                                                   jmid,
                                                   (jint)offset);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_text);
 
   if (jresult == JNI_TRUE)
   {
--- a/jni/src/jawvalue.c
+++ b/jni/src/jawvalue.c
@@ -62,7 +62,7 @@ jaw_value_data_init (jobject ac)
                                           "<init>",
                                           "(Ljavax/accessibility/AccessibleContext;)V");
   jobject jatk_value = (*jniEnv)->NewObject(jniEnv, classValue, jmid, ac);
-  data->atk_value = (*jniEnv)->NewGlobalRef(jniEnv, jatk_value);
+  data->atk_value = (*jniEnv)->NewWeakGlobalRef(jniEnv, jatk_value);
 
   return data;
 }
@@ -75,7 +75,7 @@ jaw_value_data_finalize (gpointer p)
 
   if (data && data->atk_value)
   {
-    (*jniEnv)->DeleteGlobalRef(jniEnv, data->atk_value);
+    (*jniEnv)->DeleteWeakGlobalRef(jniEnv, data->atk_value);
     data->atk_value = NULL;
   }
 }
@@ -153,9 +153,12 @@ jaw_value_get_current_value (AtkValue *o
 
   JawObject *jaw_obj = JAW_OBJECT(obj);
   ValueData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_VALUE);
-  jobject atk_value = data->atk_value;
-
   JNIEnv *jniEnv = jaw_util_get_jni_env();
+  jobject atk_value = (*jniEnv)->NewGlobalRef(jniEnv, data->atk_value);
+  if (!atk_value) {
+    return;
+  }
+
   jclass classAtkValue = (*jniEnv)->FindClass(jniEnv,
                                               "org/GNOME/Accessibility/AtkValue");
   jmethodID jmid = (*jniEnv)->GetMethodID(jniEnv,
@@ -165,6 +168,7 @@ jaw_value_get_current_value (AtkValue *o
   jobject jnumber = (*jniEnv)->CallObjectMethod(jniEnv,
                                                 atk_value,
                                                 jmid);
+  (*jniEnv)->DeleteGlobalRef(jniEnv, atk_value);
 
   if (!jnumber)
   {
@@ -182,15 +186,19 @@ jaw_value_set_value(AtkValue *obj, const
 
   JawObject *jaw_obj = JAW_OBJECT(obj);
   ValueData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_VALUE);
-  jobject atk_value = data->atk_value;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_value = (*env)->NewGlobalRef(env, data->atk_value);
+  if (!atk_value) {
+    return;
+  }
+
   jclass classAtkValue = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkValue");
   jmethodID jmid = (*env)->GetMethodID(env,
                                        classAtkValue,
                                           "setValue",
                                           "(Ljava/lang/Number;)V");
   (*env)->CallVoidMethod(env, atk_value, jmid,(jdouble)value);
+  (*env)->DeleteGlobalRef(env, atk_value);
 }
 
 static AtkRange*
@@ -199,15 +207,20 @@ jaw_value_get_range(AtkValue *obj)
 
   JawObject *jaw_obj = JAW_OBJECT(obj);
   ValueData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_VALUE);
-  jobject atk_value = data->atk_value;
-
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_value = (*env)->NewGlobalRef(env, data->atk_value);
+  if (!atk_value) {
+    return NULL;
+  }
+
   jclass classAtkValue = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkValue");
   jmethodID jmidMin = (*env)->GetMethodID(env, classAtkValue, "getMinimumValue", "()D");
   jmethodID jmidMax = (*env)->GetMethodID(env, classAtkValue, "getMaximumValue", "()D");
-  return atk_range_new((gdouble)(*env)->CallDoubleMethod(env, atk_value, jmidMin),
+  AtkRange *ret = atk_range_new((gdouble)(*env)->CallDoubleMethod(env, atk_value, jmidMin),
                        (gdouble)(*env)->CallDoubleMethod(env, atk_value, jmidMax),
                        NULL); // NULL description
+  (*env)->DeleteGlobalRef(env, atk_value);
+  return ret;
 }
 
 static gdouble
@@ -215,11 +228,16 @@ jaw_value_get_increment (AtkValue *obj)
 {
   JawObject *jaw_obj = JAW_OBJECT(obj);
   ValueData *data = jaw_object_get_interface_data(jaw_obj, INTERFACE_VALUE);
-  jobject atk_value = data->atk_value;
   JNIEnv *env = jaw_util_get_jni_env();
+  jobject atk_value = (*env)->NewGlobalRef(env, data->atk_value);
+  if (!atk_value) {
+    return 0.;
+  }
   jclass classAtkValue = (*env)->FindClass(env, "org/GNOME/Accessibility/AtkValue");
   jmethodID jmid = (*env)->GetMethodID(env, classAtkValue, "getIncrement", "()D");
-  return (*env)->CallDoubleMethod(env, atk_value, jmid);
+  gdouble ret = (*env)->CallDoubleMethod(env, atk_value, jmid);
+  (*env)->DeleteGlobalRef(env, atk_value);
+  return ret;
 }
 
 #ifdef __cplusplus
--- a/jni/src/jawutil.c
+++ b/jni/src/jawutil.c
@@ -208,6 +208,7 @@ jaw_util_get_tflag_from_jobj(JNIEnv *jni
                                             "()Ljavax/accessibility/AccessibleContext;");
     ac = (*jniEnv)->CallObjectMethod(jniEnv, jObj, jmid);
   } else {
+    (*jniEnv)->DeleteGlobalRef(jniEnv, jObj);
     return 0;
   }
 
