diff --git a/src/test/java/com/yahoo/sketches/hive/tuple/DataToArrayOfDoublesSketchUDAFTest.java b/src/test/java/com/yahoo/sketches/hive/tuple/DataToArrayOfDoublesSketchUDAFTest.java
index 8bcbee6..c443301 100644
--- a/src/test/java/com/yahoo/sketches/hive/tuple/DataToArrayOfDoublesSketchUDAFTest.java
+++ b/src/test/java/com/yahoo/sketches/hive/tuple/DataToArrayOfDoublesSketchUDAFTest.java
@@ -142,97 +142,94 @@
   public void partial1ModeIntKeysDefaultParams() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { intInspector, doubleInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new DataToArrayOfDoublesSketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.PARTIAL1, inspectors);
-    checkIntermediateResultInspector(resultInspector);
-
-    ArrayOfDoublesState state = (ArrayOfDoublesState) eval.getNewAggregationBuffer();
-    eval.iterate(state, new Object[] {new IntWritable(1), new DoubleWritable(1.0)});
-    eval.iterate(state, new Object[] {new IntWritable(2), new DoubleWritable(1.0)});
-
-    Object result = eval.terminatePartial(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof List);
-    List<?> r = (List<?>) result;
-    Assert.assertEquals(r.size(), 3);
-    Assert.assertEquals(((IntWritable) (r.get(0))).get(), DEFAULT_NOMINAL_ENTRIES);
-    Assert.assertEquals(((IntWritable) (r.get(1))).get(), 1);
-    ArrayOfDoublesSketch resultSketch = ArrayOfDoublesSketches.wrapSketch(Memory.wrap(((BytesWritable) (r.get(2))).getBytes()));
-    Assert.assertFalse(resultSketch.isEstimationMode());
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-
-    eval.close();
+    try (GenericUDAFEvaluator eval = new DataToArrayOfDoublesSketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.PARTIAL1, inspectors);
+      checkIntermediateResultInspector(resultInspector);
+  
+      ArrayOfDoublesState state = (ArrayOfDoublesState) eval.getNewAggregationBuffer();
+      eval.iterate(state, new Object[] {new IntWritable(1), new DoubleWritable(1.0)});
+      eval.iterate(state, new Object[] {new IntWritable(2), new DoubleWritable(1.0)});
+  
+      Object result = eval.terminatePartial(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof List);
+      List<?> r = (List<?>) result;
+      Assert.assertEquals(r.size(), 3);
+      Assert.assertEquals(((IntWritable) (r.get(0))).get(), DEFAULT_NOMINAL_ENTRIES);
+      Assert.assertEquals(((IntWritable) (r.get(1))).get(), 1);
+      ArrayOfDoublesSketch resultSketch = ArrayOfDoublesSketches.wrapSketch(Memory.wrap(((BytesWritable) (r.get(2))).getBytes()));
+      Assert.assertFalse(resultSketch.isEstimationMode());
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+    }
   }
 
   @Test
   public void partial1ModeStringKeysExplicitParams() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { stringInspector, doubleInspector, doubleInspector, intInspector, floatInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new DataToArrayOfDoublesSketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.PARTIAL1, inspectors);
-    checkIntermediateResultInspector(resultInspector);
-
-    ArrayOfDoublesState state = (ArrayOfDoublesState) eval.getNewAggregationBuffer();
-    eval.iterate(state, new Object[] {new Text("a"), new DoubleWritable(1), new DoubleWritable(2), new IntWritable(32), new FloatWritable(0.99f)});
-    eval.iterate(state, new Object[] {new Text("b"), new DoubleWritable(1), new DoubleWritable(2), new IntWritable(32), new FloatWritable(0.99f)});
-
-    Object result = eval.terminatePartial(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof List);
-    List<?> r = (List<?>) result;
-    Assert.assertEquals(r.size(), 3);
-    Assert.assertEquals(((IntWritable) (r.get(0))).get(), 32);
-    Assert.assertEquals(((IntWritable) (r.get(1))).get(), 2);
-    ArrayOfDoublesSketch resultSketch = ArrayOfDoublesSketches.wrapSketch(Memory.wrap(((BytesWritable) (r.get(2))).getBytes()));
-    // because of sampling probability < 1
-    Assert.assertTrue(resultSketch.isEstimationMode());
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0, 0.05);
-
-    eval.close();
-  }
+    try (GenericUDAFEvaluator eval = new DataToArrayOfDoublesSketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.PARTIAL1, inspectors);
+      checkIntermediateResultInspector(resultInspector);
+  
+      ArrayOfDoublesState state = (ArrayOfDoublesState) eval.getNewAggregationBuffer();
+      eval.iterate(state, new Object[] {new Text("a"), new DoubleWritable(1), new DoubleWritable(2), new IntWritable(32), new FloatWritable(0.99f)});
+      eval.iterate(state, new Object[] {new Text("b"), new DoubleWritable(1), new DoubleWritable(2), new IntWritable(32), new FloatWritable(0.99f)});
+  
+      Object result = eval.terminatePartial(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof List);
+      List<?> r = (List<?>) result;
+      Assert.assertEquals(r.size(), 3);
+      Assert.assertEquals(((IntWritable) (r.get(0))).get(), 32);
+      Assert.assertEquals(((IntWritable) (r.get(1))).get(), 2);
+      ArrayOfDoublesSketch resultSketch = ArrayOfDoublesSketches.wrapSketch(Memory.wrap(((BytesWritable) (r.get(2))).getBytes()));
+      // because of sampling probability < 1
+      Assert.assertTrue(resultSketch.isEstimationMode());
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0, 0.05);
+    }
+}
 
   // PARTIAL2 mode (Combine phase in Map-Reduce): merge + terminatePartial
   @Test
   public void partial2Mode() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { intInspector, doubleInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new DataToArrayOfDoublesSketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.PARTIAL2, new ObjectInspector[] {structInspector});
-    checkIntermediateResultInspector(resultInspector);
-
-    ArrayOfDoublesState state = (ArrayOfDoublesState) eval.getNewAggregationBuffer();
-
-    ArrayOfDoublesUpdatableSketch sketch1 = new ArrayOfDoublesUpdatableSketchBuilder().build();
-    sketch1.update(1, new double[] {1});
-    eval.merge(state, Arrays.asList(
-      new IntWritable(DEFAULT_NOMINAL_ENTRIES),
-      new IntWritable(1),
-      new BytesWritable(sketch1.compact().toByteArray()))
-    );
-
-    ArrayOfDoublesUpdatableSketch sketch2 = new ArrayOfDoublesUpdatableSketchBuilder().build();
-    sketch2.update(2, new double[] {1});
-    eval.merge(state, Arrays.asList(
-      new IntWritable(DEFAULT_NOMINAL_ENTRIES),
-      new IntWritable(1),
-      new BytesWritable(sketch2.compact().toByteArray()))
-    );
-
-    Object result = eval.terminatePartial(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof List);
-    List<?> r = (List<?>) result;
-    Assert.assertEquals(r.size(), 3);
-    Assert.assertEquals(((IntWritable) (r.get(0))).get(), DEFAULT_NOMINAL_ENTRIES);
-    Assert.assertEquals(((IntWritable) (r.get(1))).get(), 1);
-    ArrayOfDoublesSketch resultSketch = ArrayOfDoublesSketches.wrapSketch(Memory.wrap(((BytesWritable) (r.get(2))).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-
-    eval.reset(state);
-    result = eval.terminate(state);
-    Assert.assertNull(result);
-
-    eval.close();
+    try (GenericUDAFEvaluator eval = new DataToArrayOfDoublesSketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.PARTIAL2, new ObjectInspector[] {structInspector});
+      checkIntermediateResultInspector(resultInspector);
+  
+      ArrayOfDoublesState state = (ArrayOfDoublesState) eval.getNewAggregationBuffer();
+  
+      ArrayOfDoublesUpdatableSketch sketch1 = new ArrayOfDoublesUpdatableSketchBuilder().build();
+      sketch1.update(1, new double[] {1});
+      eval.merge(state, Arrays.asList(
+        new IntWritable(DEFAULT_NOMINAL_ENTRIES),
+        new IntWritable(1),
+        new BytesWritable(sketch1.compact().toByteArray()))
+      );
+  
+      ArrayOfDoublesUpdatableSketch sketch2 = new ArrayOfDoublesUpdatableSketchBuilder().build();
+      sketch2.update(2, new double[] {1});
+      eval.merge(state, Arrays.asList(
+        new IntWritable(DEFAULT_NOMINAL_ENTRIES),
+        new IntWritable(1),
+        new BytesWritable(sketch2.compact().toByteArray()))
+      );
+  
+      Object result = eval.terminatePartial(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof List);
+      List<?> r = (List<?>) result;
+      Assert.assertEquals(r.size(), 3);
+      Assert.assertEquals(((IntWritable) (r.get(0))).get(), DEFAULT_NOMINAL_ENTRIES);
+      Assert.assertEquals(((IntWritable) (r.get(1))).get(), 1);
+      ArrayOfDoublesSketch resultSketch = ArrayOfDoublesSketches.wrapSketch(Memory.wrap(((BytesWritable) (r.get(2))).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+  
+      eval.reset(state);
+      result = eval.terminate(state);
+      Assert.assertNull(result);
+    }
   }
 
   // FINAL mode (Reduce phase in Map-Reduce): merge + terminate
@@ -240,35 +237,34 @@
   public void finalMode() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { intInspector, doubleInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new DataToArrayOfDoublesSketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.FINAL, new ObjectInspector[] {structInspector});
-    checkFinalResultInspector(resultInspector);
-
-    ArrayOfDoublesState state = (ArrayOfDoublesState) eval.getNewAggregationBuffer();
-
-    ArrayOfDoublesUpdatableSketch sketch1 = new ArrayOfDoublesUpdatableSketchBuilder().build();
-    sketch1.update(1, new double[] {1});
-    eval.merge(state, Arrays.asList(
-      new IntWritable(DEFAULT_NOMINAL_ENTRIES),
-      new IntWritable(1),
-      new BytesWritable(sketch1.compact().toByteArray()))
-    );
-
-    ArrayOfDoublesUpdatableSketch sketch2 = new ArrayOfDoublesUpdatableSketchBuilder().build();
-    sketch2.update(2, new double[] {1});
-    eval.merge(state, Arrays.asList(
-      new IntWritable(DEFAULT_NOMINAL_ENTRIES),
-      new IntWritable(1),
-      new BytesWritable(sketch2.compact().toByteArray()))
-    );
-
-    Object result = eval.terminate(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof BytesWritable);
-    ArrayOfDoublesSketch resultSketch = ArrayOfDoublesSketches.wrapSketch(Memory.wrap(((BytesWritable) result).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-
-    eval.close();
+    try (GenericUDAFEvaluator eval = new DataToArrayOfDoublesSketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.FINAL, new ObjectInspector[] {structInspector});
+      checkFinalResultInspector(resultInspector);
+  
+      ArrayOfDoublesState state = (ArrayOfDoublesState) eval.getNewAggregationBuffer();
+  
+      ArrayOfDoublesUpdatableSketch sketch1 = new ArrayOfDoublesUpdatableSketchBuilder().build();
+      sketch1.update(1, new double[] {1});
+      eval.merge(state, Arrays.asList(
+        new IntWritable(DEFAULT_NOMINAL_ENTRIES),
+        new IntWritable(1),
+        new BytesWritable(sketch1.compact().toByteArray()))
+      );
+  
+      ArrayOfDoublesUpdatableSketch sketch2 = new ArrayOfDoublesUpdatableSketchBuilder().build();
+      sketch2.update(2, new double[] {1});
+      eval.merge(state, Arrays.asList(
+        new IntWritable(DEFAULT_NOMINAL_ENTRIES),
+        new IntWritable(1),
+        new BytesWritable(sketch2.compact().toByteArray()))
+      );
+  
+      Object result = eval.terminate(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof BytesWritable);
+      ArrayOfDoublesSketch resultSketch = ArrayOfDoublesSketches.wrapSketch(Memory.wrap(((BytesWritable) result).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+    }
   }
 
   // COMPLETE mode (single mode, alternative to MapReduce): iterate + terminate
@@ -276,79 +272,76 @@
   public void completeModeIntKeysDefaultParams() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { intInspector, doubleInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new DataToArrayOfDoublesSketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
-    checkFinalResultInspector(resultInspector);
-
-    ArrayOfDoublesState state = (ArrayOfDoublesState) eval.getNewAggregationBuffer();
-    eval.iterate(state, new Object[] {new IntWritable(1), new DoubleWritable(1)});
-    eval.iterate(state, new Object[] {new IntWritable(2), new DoubleWritable(1)});
-
-    Object result = eval.terminate(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof BytesWritable);
-    ArrayOfDoublesSketch resultSketch = ArrayOfDoublesSketches.wrapSketch(Memory.wrap(((BytesWritable) result).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-
-    eval.reset(state);
-    result = eval.terminate(state);
-    Assert.assertNull(result);
-
-    eval.close();
+    try (GenericUDAFEvaluator eval = new DataToArrayOfDoublesSketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
+      checkFinalResultInspector(resultInspector);
+  
+      ArrayOfDoublesState state = (ArrayOfDoublesState) eval.getNewAggregationBuffer();
+      eval.iterate(state, new Object[] {new IntWritable(1), new DoubleWritable(1)});
+      eval.iterate(state, new Object[] {new IntWritable(2), new DoubleWritable(1)});
+  
+      Object result = eval.terminate(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof BytesWritable);
+      ArrayOfDoublesSketch resultSketch = ArrayOfDoublesSketches.wrapSketch(Memory.wrap(((BytesWritable) result).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+  
+      eval.reset(state);
+      result = eval.terminate(state);
+      Assert.assertNull(result);
+    }
   }
 
   @Test
   public void completeModeDoubleKeysExplicitParams() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { doubleInspector, doubleInspector, doubleInspector, intInspector, floatInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new DataToArrayOfDoublesSketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
-    checkFinalResultInspector(resultInspector);
-
-    ArrayOfDoublesState state = (ArrayOfDoublesState) eval.getNewAggregationBuffer();
-    eval.iterate(state, new Object[] {new DoubleWritable(1), new DoubleWritable(1), new DoubleWritable(2), new IntWritable(32), new FloatWritable(0.99f)});
-    eval.iterate(state, new Object[] {new DoubleWritable(2), new DoubleWritable(1), new DoubleWritable(2), new IntWritable(32), new FloatWritable(0.99f)});
-
-    Object result = eval.terminate(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof BytesWritable);
-    ArrayOfDoublesSketch resultSketch = ArrayOfDoublesSketches.wrapSketch(Memory.wrap(((BytesWritable) result).getBytes()));
-    // because of sampling probability < 1
-    Assert.assertTrue(resultSketch.isEstimationMode());
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0, 0.05);
-
-    eval.reset(state);
-    result = eval.terminate(state);
-    Assert.assertNull(result);
-
-    eval.close();
+    try (GenericUDAFEvaluator eval = new DataToArrayOfDoublesSketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
+      checkFinalResultInspector(resultInspector);
+  
+      ArrayOfDoublesState state = (ArrayOfDoublesState) eval.getNewAggregationBuffer();
+      eval.iterate(state, new Object[] {new DoubleWritable(1), new DoubleWritable(1), new DoubleWritable(2), new IntWritable(32), new FloatWritable(0.99f)});
+      eval.iterate(state, new Object[] {new DoubleWritable(2), new DoubleWritable(1), new DoubleWritable(2), new IntWritable(32), new FloatWritable(0.99f)});
+  
+      Object result = eval.terminate(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof BytesWritable);
+      ArrayOfDoublesSketch resultSketch = ArrayOfDoublesSketches.wrapSketch(Memory.wrap(((BytesWritable) result).getBytes()));
+      // because of sampling probability < 1
+      Assert.assertTrue(resultSketch.isEstimationMode());
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0, 0.05);
+  
+      eval.reset(state);
+      result = eval.terminate(state);
+      Assert.assertNull(result);
+    }
   }
 
   @Test
   public void completeModeCheckTrimmingToNominal() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { intInspector, doubleInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new DataToArrayOfDoublesSketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
-    checkFinalResultInspector(resultInspector);
-
-    ArrayOfDoublesState state = (ArrayOfDoublesState) eval.getNewAggregationBuffer();
-    for (int i = 0; i < 10000; i++) {
-      eval.iterate(state, new Object[] {new IntWritable(i), new DoubleWritable(1)});
+    try (GenericUDAFEvaluator eval = new DataToArrayOfDoublesSketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
+      checkFinalResultInspector(resultInspector);
+  
+      ArrayOfDoublesState state = (ArrayOfDoublesState) eval.getNewAggregationBuffer();
+      for (int i = 0; i < 10000; i++) {
+        eval.iterate(state, new Object[] {new IntWritable(i), new DoubleWritable(1)});
+      }
+  
+      Object result = eval.terminate(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof BytesWritable);
+      ArrayOfDoublesSketch resultSketch = ArrayOfDoublesSketches.wrapSketch(Memory.wrap(((BytesWritable) result).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 10000.0, 10000 * 0.03);
+      Assert.assertTrue(resultSketch.getRetainedEntries() <= 4096, "retained entries: " + resultSketch.getRetainedEntries());
+  
+      eval.reset(state);
+      result = eval.terminate(state);
+      Assert.assertNull(result);
     }
-
-    Object result = eval.terminate(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof BytesWritable);
-    ArrayOfDoublesSketch resultSketch = ArrayOfDoublesSketches.wrapSketch(Memory.wrap(((BytesWritable) result).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 10000.0, 10000 * 0.03);
-    Assert.assertTrue(resultSketch.getRetainedEntries() <= 4096, "retained entries: " + resultSketch.getRetainedEntries());
-
-    eval.reset(state);
-    result = eval.terminate(state);
-    Assert.assertNull(result);
-
-    eval.close();
   }
 
   static void checkIntermediateResultInspector(ObjectInspector resultInspector) {
diff --git a/src/test/java/com/yahoo/sketches/hive/tuple/DataToDoubleSummarySketchUDAFTest.java b/src/test/java/com/yahoo/sketches/hive/tuple/DataToDoubleSummarySketchUDAFTest.java
index 6f8c9d4..5cf057e 100644
--- a/src/test/java/com/yahoo/sketches/hive/tuple/DataToDoubleSummarySketchUDAFTest.java
+++ b/src/test/java/com/yahoo/sketches/hive/tuple/DataToDoubleSummarySketchUDAFTest.java
@@ -130,53 +130,51 @@
   public void partial1ModeIntKeysDefaultParams() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { intInspector, doubleInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new DataToDoubleSummarySketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.PARTIAL1, inspectors);
-    checkIntermediateResultInspector(resultInspector);
-
-    @SuppressWarnings("unchecked")
-    State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
-    eval.iterate(state, new Object[] {new IntWritable(1), new DoubleWritable(1)});
-    eval.iterate(state, new Object[] {new IntWritable(2), new DoubleWritable(1)});
-
-    Object result = eval.terminatePartial(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof List);
-    List<?> r = (List<?>) result;
-    Assert.assertEquals(r.size(), 2);
-    Assert.assertEquals(((IntWritable) r.get(0)).get(), DEFAULT_NOMINAL_ENTRIES);
-    Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) r.get(1)).getBytes()));
-    Assert.assertFalse(resultSketch.isEstimationMode());
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-
-    eval.close();
+    try (GenericUDAFEvaluator eval = new DataToDoubleSummarySketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.PARTIAL1, inspectors);
+      checkIntermediateResultInspector(resultInspector);
+    
+      @SuppressWarnings("unchecked")
+      State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
+      eval.iterate(state, new Object[] {new IntWritable(1), new DoubleWritable(1)});
+      eval.iterate(state, new Object[] {new IntWritable(2), new DoubleWritable(1)});
+    
+      Object result = eval.terminatePartial(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof List);
+      List<?> r = (List<?>) result;
+      Assert.assertEquals(r.size(), 2);
+      Assert.assertEquals(((IntWritable) r.get(0)).get(), DEFAULT_NOMINAL_ENTRIES);
+      Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) r.get(1)).getBytes()));
+      Assert.assertFalse(resultSketch.isEstimationMode());
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+    }
   }
 
   @Test
   public void partial1ModeStringKeysExplicitParams() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { stringInspector, doubleInspector, intInspector, floatInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new DataToDoubleSummarySketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.PARTIAL1, inspectors);
-    checkIntermediateResultInspector(resultInspector);
-
-    @SuppressWarnings("unchecked")
-    State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
-    eval.iterate(state, new Object[] {new Text("a"), new DoubleWritable(1), new IntWritable(32), new FloatWritable(0.99f)});
-    eval.iterate(state, new Object[] {new Text("b"), new DoubleWritable(1), new IntWritable(32), new FloatWritable(0.99f)});
-
-    Object result = eval.terminatePartial(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof List);
-    List<?> r = (List<?>) result;
-    Assert.assertEquals(r.size(), 2);
-    Assert.assertEquals(((IntWritable) r.get(0)).get(), 32);
-    Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) r.get(1)).getBytes()));
-    // because of sampling probability < 1
-    Assert.assertTrue(resultSketch.isEstimationMode());
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0, 0.05);
-
-    eval.close();
+    try (GenericUDAFEvaluator eval = new DataToDoubleSummarySketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.PARTIAL1, inspectors);
+      checkIntermediateResultInspector(resultInspector);
+  
+      @SuppressWarnings("unchecked")
+      State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
+      eval.iterate(state, new Object[] {new Text("a"), new DoubleWritable(1), new IntWritable(32), new FloatWritable(0.99f)});
+      eval.iterate(state, new Object[] {new Text("b"), new DoubleWritable(1), new IntWritable(32), new FloatWritable(0.99f)});
+  
+      Object result = eval.terminatePartial(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof List);
+      List<?> r = (List<?>) result;
+      Assert.assertEquals(r.size(), 2);
+      Assert.assertEquals(((IntWritable) r.get(0)).get(), 32);
+      Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) r.get(1)).getBytes()));
+      // because of sampling probability < 1
+      Assert.assertTrue(resultSketch.isEstimationMode());
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0, 0.05);
+    }
   }
 
   // PARTIAL2 mode (Combine phase in Map-Reduce): merge + terminatePartial
@@ -184,41 +182,40 @@
   public void partial2Mode() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { intInspector, doubleInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new DataToDoubleSummarySketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.PARTIAL2, new ObjectInspector[] {structInspector});
-    checkIntermediateResultInspector(resultInspector);
-
-    @SuppressWarnings("unchecked")
-    State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
-
-    UpdatableSketch<Double, DoubleSummary> sketch1 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
-    sketch1.update(1, 1.0);
-    eval.merge(state, Arrays.asList(
-      new IntWritable(DEFAULT_NOMINAL_ENTRIES),
-      new BytesWritable(sketch1.compact().toByteArray()))
-    );
-
-    UpdatableSketch<Double, DoubleSummary> sketch2 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
-    sketch2.update(2, 1.0);
-    eval.merge(state, Arrays.asList(
-      new IntWritable(DEFAULT_NOMINAL_ENTRIES),
-      new BytesWritable(sketch2.compact().toByteArray()))
-    );
-
-    Object result = eval.terminatePartial(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof List);
-    List<?> r = (List<?>) result;
-    Assert.assertEquals(r.size(), 2);
-    Assert.assertEquals(((IntWritable) r.get(0)).get(), DEFAULT_NOMINAL_ENTRIES);
-    Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) r.get(1)).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-
-    eval.reset(state);
-    result = eval.terminate(state);
-    Assert.assertNull(result);
-
-    eval.close();
+    try (GenericUDAFEvaluator eval = new DataToDoubleSummarySketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.PARTIAL2, new ObjectInspector[] {structInspector});
+      checkIntermediateResultInspector(resultInspector);
+  
+      @SuppressWarnings("unchecked")
+      State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
+  
+      UpdatableSketch<Double, DoubleSummary> sketch1 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
+      sketch1.update(1, 1.0);
+      eval.merge(state, Arrays.asList(
+        new IntWritable(DEFAULT_NOMINAL_ENTRIES),
+        new BytesWritable(sketch1.compact().toByteArray()))
+      );
+  
+      UpdatableSketch<Double, DoubleSummary> sketch2 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
+      sketch2.update(2, 1.0);
+      eval.merge(state, Arrays.asList(
+        new IntWritable(DEFAULT_NOMINAL_ENTRIES),
+        new BytesWritable(sketch2.compact().toByteArray()))
+      );
+  
+      Object result = eval.terminatePartial(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof List);
+      List<?> r = (List<?>) result;
+      Assert.assertEquals(r.size(), 2);
+      Assert.assertEquals(((IntWritable) r.get(0)).get(), DEFAULT_NOMINAL_ENTRIES);
+      Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) r.get(1)).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+  
+      eval.reset(state);
+      result = eval.terminate(state);
+      Assert.assertNull(result);
+    }
   }
 
   // FINAL mode (Reduce phase in Map-Reduce): merge + terminate
@@ -226,34 +223,33 @@
   public void finalMode() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { intInspector, doubleInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new DataToDoubleSummarySketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.FINAL, new ObjectInspector[] {structInspector});
-    checkFinalResultInspector(resultInspector);
-
-    @SuppressWarnings("unchecked")
-    State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
-
-    UpdatableSketch<Double, DoubleSummary> sketch1 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
-    sketch1.update(1, 1.0);
-    eval.merge(state, Arrays.asList(
-      new IntWritable(DEFAULT_NOMINAL_ENTRIES),
-      new BytesWritable(sketch1.compact().toByteArray()))
-    );
-
-    UpdatableSketch<Double, DoubleSummary> sketch2 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
-    sketch2.update(2, 1.0);
-    eval.merge(state, Arrays.asList(
-      new IntWritable(DEFAULT_NOMINAL_ENTRIES),
-      new BytesWritable(sketch2.compact().toByteArray()))
-    );
-
-    Object result = eval.terminate(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof BytesWritable);
-    Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-
-    eval.close();
+    try (GenericUDAFEvaluator eval = new DataToDoubleSummarySketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.FINAL, new ObjectInspector[] {structInspector});
+      checkFinalResultInspector(resultInspector);
+  
+      @SuppressWarnings("unchecked")
+      State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
+  
+      UpdatableSketch<Double, DoubleSummary> sketch1 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
+      sketch1.update(1, 1.0);
+      eval.merge(state, Arrays.asList(
+        new IntWritable(DEFAULT_NOMINAL_ENTRIES),
+        new BytesWritable(sketch1.compact().toByteArray()))
+      );
+  
+      UpdatableSketch<Double, DoubleSummary> sketch2 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
+      sketch2.update(2, 1.0);
+      eval.merge(state, Arrays.asList(
+        new IntWritable(DEFAULT_NOMINAL_ENTRIES),
+        new BytesWritable(sketch2.compact().toByteArray()))
+      );
+  
+      Object result = eval.terminate(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof BytesWritable);
+      Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+    }
   }
 
   // COMPLETE mode (single mode, alternative to MapReduce): iterate + terminate
@@ -261,26 +257,25 @@
   public void completeModeIntKeysDefaultParams() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { intInspector, doubleInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new DataToDoubleSummarySketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
-    checkFinalResultInspector(resultInspector);
-
-    @SuppressWarnings("unchecked")
-    State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
-    eval.iterate(state, new Object[] {new IntWritable(1), new DoubleWritable(1)});
-    eval.iterate(state, new Object[] {new IntWritable(2), new DoubleWritable(1)});
-
-    Object result = eval.terminate(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof BytesWritable);
-    Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-
-    eval.reset(state);
-    result = eval.terminate(state);
-    Assert.assertNull(result);
-
-    eval.close();
+    try (GenericUDAFEvaluator eval = new DataToDoubleSummarySketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
+      checkFinalResultInspector(resultInspector);
+  
+      @SuppressWarnings("unchecked")
+      State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
+      eval.iterate(state, new Object[] {new IntWritable(1), new DoubleWritable(1)});
+      eval.iterate(state, new Object[] {new IntWritable(2), new DoubleWritable(1)});
+  
+      Object result = eval.terminate(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof BytesWritable);
+      Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+  
+      eval.reset(state);
+      result = eval.terminate(state);
+      Assert.assertNull(result);
+    }
   }
 
   // COMPLETE mode (single mode, alternative to MapReduce): iterate + terminate
@@ -288,56 +283,54 @@
   public void completeModeDoubleKeysExplicitParams() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { doubleInspector, doubleInspector, intInspector, floatInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new DataToDoubleSummarySketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
-    checkFinalResultInspector(resultInspector);
-
-    @SuppressWarnings("unchecked")
-    State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
-    eval.iterate(state, new Object[] {new DoubleWritable(1), new DoubleWritable(1), new IntWritable(32), new FloatWritable(0.99f)});
-    eval.iterate(state, new Object[] {new DoubleWritable(2), new DoubleWritable(1), new IntWritable(32), new FloatWritable(0.99f)});
-
-    Object result = eval.terminate(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof BytesWritable);
-    Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
-    // because of sampling probability < 1
-    Assert.assertTrue(resultSketch.isEstimationMode());
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0, 0.05);
-
-    eval.reset(state);
-    result = eval.terminate(state);
-    Assert.assertNull(result);
-
-    eval.close();
+    try (GenericUDAFEvaluator eval = new DataToDoubleSummarySketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
+      checkFinalResultInspector(resultInspector);
+  
+      @SuppressWarnings("unchecked")
+      State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
+      eval.iterate(state, new Object[] {new DoubleWritable(1), new DoubleWritable(1), new IntWritable(32), new FloatWritable(0.99f)});
+      eval.iterate(state, new Object[] {new DoubleWritable(2), new DoubleWritable(1), new IntWritable(32), new FloatWritable(0.99f)});
+  
+      Object result = eval.terminate(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof BytesWritable);
+      Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
+      // because of sampling probability < 1
+      Assert.assertTrue(resultSketch.isEstimationMode());
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0, 0.05);
+  
+      eval.reset(state);
+      result = eval.terminate(state);
+      Assert.assertNull(result);
+    }
   }
 
   @Test
   public void completeModeCheckTrimmingToNominal() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { intInspector, doubleInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new DataToDoubleSummarySketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
-    checkFinalResultInspector(resultInspector);
-
-    @SuppressWarnings("unchecked")
-    State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
-    for (int i = 0; i < 10000; i++) {
-      eval.iterate(state, new Object[] {new IntWritable(i), new DoubleWritable(1)});
+    try (GenericUDAFEvaluator eval = new DataToDoubleSummarySketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
+      checkFinalResultInspector(resultInspector);
+  
+      @SuppressWarnings("unchecked")
+      State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
+      for (int i = 0; i < 10000; i++) {
+        eval.iterate(state, new Object[] {new IntWritable(i), new DoubleWritable(1)});
+      }
+  
+      Object result = eval.terminate(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof BytesWritable);
+      Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 10000.0, 10000 * 0.03);
+      Assert.assertTrue(resultSketch.getRetainedEntries() <= 4096, "retained entries: " + resultSketch.getRetainedEntries());
+  
+      eval.reset(state);
+      result = eval.terminate(state);
+      Assert.assertNull(result);
     }
-
-    Object result = eval.terminate(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof BytesWritable);
-    Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 10000.0, 10000 * 0.03);
-    Assert.assertTrue(resultSketch.getRetainedEntries() <= 4096, "retained entries: " + resultSketch.getRetainedEntries());
-
-    eval.reset(state);
-    result = eval.terminate(state);
-    Assert.assertNull(result);
-
-    eval.close();
   }
 
   static void checkIntermediateResultInspector(ObjectInspector resultInspector) {
diff --git a/src/test/java/com/yahoo/sketches/hive/tuple/DataToDoubleSummaryWithModeSketchUDAFTest.java b/src/test/java/com/yahoo/sketches/hive/tuple/DataToDoubleSummaryWithModeSketchUDAFTest.java
index e59ab85..137b50f 100644
--- a/src/test/java/com/yahoo/sketches/hive/tuple/DataToDoubleSummaryWithModeSketchUDAFTest.java
+++ b/src/test/java/com/yahoo/sketches/hive/tuple/DataToDoubleSummaryWithModeSketchUDAFTest.java
@@ -131,67 +131,65 @@
   public void partial1ModeIntKeysDefaultParams() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { intInspector, doubleInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new DataToDoubleSummaryWithModeSketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.PARTIAL1, inspectors);
-    checkIntermediateResultInspector(resultInspector);
-
-    @SuppressWarnings("unchecked")
-    State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
-    eval.iterate(state, new Object[] {new IntWritable(1), new DoubleWritable(1)});
-    eval.iterate(state, new Object[] {new IntWritable(2), new DoubleWritable(2)});
-    eval.iterate(state, new Object[] {new IntWritable(1), new DoubleWritable(2)});
-    eval.iterate(state, new Object[] {new IntWritable(2), new DoubleWritable(1)});
-
-    Object result = eval.terminatePartial(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof List);
-    List<?> r = (List<?>) result;
-    Assert.assertEquals(r.size(), 3);
-    Assert.assertEquals(((IntWritable) r.get(0)).get(), DEFAULT_NOMINAL_ENTRIES);
-    Assert.assertEquals(((Text) r.get(1)).toString(), DoubleSummary.Mode.Sum.toString());
-    Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) r.get(2)).getBytes()));
-    Assert.assertFalse(resultSketch.isEstimationMode());
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-    SketchIterator<DoubleSummary> it = resultSketch.iterator();
-    while (it.next()) {
-      Assert.assertEquals(it.getSummary().getValue(), 3.0);
+    try (GenericUDAFEvaluator eval = new DataToDoubleSummaryWithModeSketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.PARTIAL1, inspectors);
+      checkIntermediateResultInspector(resultInspector);
+  
+      @SuppressWarnings("unchecked")
+      State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
+      eval.iterate(state, new Object[] {new IntWritable(1), new DoubleWritable(1)});
+      eval.iterate(state, new Object[] {new IntWritable(2), new DoubleWritable(2)});
+      eval.iterate(state, new Object[] {new IntWritable(1), new DoubleWritable(2)});
+      eval.iterate(state, new Object[] {new IntWritable(2), new DoubleWritable(1)});
+  
+      Object result = eval.terminatePartial(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof List);
+      List<?> r = (List<?>) result;
+      Assert.assertEquals(r.size(), 3);
+      Assert.assertEquals(((IntWritable) r.get(0)).get(), DEFAULT_NOMINAL_ENTRIES);
+      Assert.assertEquals(((Text) r.get(1)).toString(), DoubleSummary.Mode.Sum.toString());
+      Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) r.get(2)).getBytes()));
+      Assert.assertFalse(resultSketch.isEstimationMode());
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+      SketchIterator<DoubleSummary> it = resultSketch.iterator();
+      while (it.next()) {
+        Assert.assertEquals(it.getSummary().getValue(), 3.0);
+      }
     }
-
-    eval.close();
   }
 
   @Test
   public void partial1ModeStringKeysExplicitParams() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { stringInspector, doubleInspector, intInspector, floatInspector, stringInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new DataToDoubleSummaryWithModeSketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.PARTIAL1, inspectors);
-    checkIntermediateResultInspector(resultInspector);
-
-    @SuppressWarnings("unchecked")
-    State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
-    eval.iterate(state, new Object[] {new Text("a"), new DoubleWritable(1), new IntWritable(32), new FloatWritable(0.99f), new Text("Min")});
-    eval.iterate(state, new Object[] {new Text("b"), new DoubleWritable(2), new IntWritable(32), new FloatWritable(0.99f), new Text("Min")});
-    eval.iterate(state, new Object[] {new Text("a"), new DoubleWritable(2), new IntWritable(32), new FloatWritable(0.99f), new Text("Min")});
-    eval.iterate(state, new Object[] {new Text("b"), new DoubleWritable(1), new IntWritable(32), new FloatWritable(0.99f), new Text("Min")});
-
-    Object result = eval.terminatePartial(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof List);
-    List<?> r = (List<?>) result;
-    Assert.assertEquals(r.size(), 3);
-    Assert.assertEquals(((IntWritable) r.get(0)).get(), 32);
-    Assert.assertEquals(((Text) r.get(1)).toString(), DoubleSummary.Mode.Min.toString());
-    Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) r.get(2)).getBytes()));
-    // because of sampling probability < 1
-    Assert.assertTrue(resultSketch.isEstimationMode());
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0, 0.05);
-    SketchIterator<DoubleSummary> it = resultSketch.iterator();
-    while (it.next()) {
-      Assert.assertEquals(it.getSummary().getValue(), 1.0);
+    try (GenericUDAFEvaluator eval = new DataToDoubleSummaryWithModeSketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.PARTIAL1, inspectors);
+      checkIntermediateResultInspector(resultInspector);
+  
+      @SuppressWarnings("unchecked")
+      State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
+      eval.iterate(state, new Object[] {new Text("a"), new DoubleWritable(1), new IntWritable(32), new FloatWritable(0.99f), new Text("Min")});
+      eval.iterate(state, new Object[] {new Text("b"), new DoubleWritable(2), new IntWritable(32), new FloatWritable(0.99f), new Text("Min")});
+      eval.iterate(state, new Object[] {new Text("a"), new DoubleWritable(2), new IntWritable(32), new FloatWritable(0.99f), new Text("Min")});
+      eval.iterate(state, new Object[] {new Text("b"), new DoubleWritable(1), new IntWritable(32), new FloatWritable(0.99f), new Text("Min")});
+  
+      Object result = eval.terminatePartial(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof List);
+      List<?> r = (List<?>) result;
+      Assert.assertEquals(r.size(), 3);
+      Assert.assertEquals(((IntWritable) r.get(0)).get(), 32);
+      Assert.assertEquals(((Text) r.get(1)).toString(), DoubleSummary.Mode.Min.toString());
+      Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) r.get(2)).getBytes()));
+      // because of sampling probability < 1
+      Assert.assertTrue(resultSketch.isEstimationMode());
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0, 0.05);
+      SketchIterator<DoubleSummary> it = resultSketch.iterator();
+      while (it.next()) {
+        Assert.assertEquals(it.getSummary().getValue(), 1.0);
+      }
     }
-
-    eval.close();
   }
 
   // PARTIAL2 mode (Combine phase in Map-Reduce): merge + terminatePartial
@@ -199,50 +197,49 @@
   public void partial2Mode() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { intInspector, doubleInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new DataToDoubleSummaryWithModeSketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.PARTIAL2, new ObjectInspector[] {structInspector});
-    checkIntermediateResultInspector(resultInspector);
-
-    @SuppressWarnings("unchecked")
-    State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
-
-    UpdatableSketch<Double, DoubleSummary> sketch1 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
-    sketch1.update(1, 1.0);
-    sketch1.update(2, 2.0);
-    eval.merge(state, Arrays.asList(
-      new IntWritable(DEFAULT_NOMINAL_ENTRIES),
-      new Text("Sum"),
-      new BytesWritable(sketch1.compact().toByteArray()))
-    );
-
-    UpdatableSketch<Double, DoubleSummary> sketch2 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
-    sketch2.update(1, 2.0);
-    sketch2.update(2, 1.0);
-    eval.merge(state, Arrays.asList(
-      new IntWritable(DEFAULT_NOMINAL_ENTRIES),
-      new Text("Sum"),
-      new BytesWritable(sketch2.compact().toByteArray()))
-    );
-
-    Object result = eval.terminatePartial(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof List);
-    List<?> r = (List<?>) result;
-    Assert.assertEquals(r.size(), 3);
-    Assert.assertEquals(((IntWritable) r.get(0)).get(), DEFAULT_NOMINAL_ENTRIES);
-    Assert.assertEquals(((Text) r.get(1)).toString(), DoubleSummary.Mode.Sum.toString());
-    Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) r.get(2)).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-    SketchIterator<DoubleSummary> it = resultSketch.iterator();
-    while (it.next()) {
-      Assert.assertEquals(it.getSummary().getValue(), 3.0);
+    try (GenericUDAFEvaluator eval = new DataToDoubleSummaryWithModeSketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.PARTIAL2, new ObjectInspector[] {structInspector});
+      checkIntermediateResultInspector(resultInspector);
+  
+      @SuppressWarnings("unchecked")
+      State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
+  
+      UpdatableSketch<Double, DoubleSummary> sketch1 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
+      sketch1.update(1, 1.0);
+      sketch1.update(2, 2.0);
+      eval.merge(state, Arrays.asList(
+        new IntWritable(DEFAULT_NOMINAL_ENTRIES),
+        new Text("Sum"),
+        new BytesWritable(sketch1.compact().toByteArray()))
+      );
+  
+      UpdatableSketch<Double, DoubleSummary> sketch2 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
+      sketch2.update(1, 2.0);
+      sketch2.update(2, 1.0);
+      eval.merge(state, Arrays.asList(
+        new IntWritable(DEFAULT_NOMINAL_ENTRIES),
+        new Text("Sum"),
+        new BytesWritable(sketch2.compact().toByteArray()))
+      );
+  
+      Object result = eval.terminatePartial(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof List);
+      List<?> r = (List<?>) result;
+      Assert.assertEquals(r.size(), 3);
+      Assert.assertEquals(((IntWritable) r.get(0)).get(), DEFAULT_NOMINAL_ENTRIES);
+      Assert.assertEquals(((Text) r.get(1)).toString(), DoubleSummary.Mode.Sum.toString());
+      Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) r.get(2)).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+      SketchIterator<DoubleSummary> it = resultSketch.iterator();
+      while (it.next()) {
+        Assert.assertEquals(it.getSummary().getValue(), 3.0);
+      }
+  
+      eval.reset(state);
+      result = eval.terminate(state);
+      Assert.assertNull(result);
     }
-
-    eval.reset(state);
-    result = eval.terminate(state);
-    Assert.assertNull(result);
-
-    eval.close();
   }
 
   // FINAL mode (Reduce phase in Map-Reduce): merge + terminate
@@ -250,42 +247,41 @@
   public void finalMode() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { intInspector, doubleInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new DataToDoubleSummaryWithModeSketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.FINAL, new ObjectInspector[] {structInspector});
-    checkFinalResultInspector(resultInspector);
-
-    @SuppressWarnings("unchecked")
-    State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
-
-    UpdatableSketch<Double, DoubleSummary> sketch1 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
-    sketch1.update(1, 1.0);
-    sketch1.update(2, 2.0);
-    eval.merge(state, Arrays.asList(
-      new IntWritable(DEFAULT_NOMINAL_ENTRIES),
-      new Text("Sum"),
-      new BytesWritable(sketch1.compact().toByteArray()))
-    );
-
-    UpdatableSketch<Double, DoubleSummary> sketch2 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
-    sketch2.update(1, 2.0);
-    sketch2.update(2, 1.0);
-    eval.merge(state, Arrays.asList(
-      new IntWritable(DEFAULT_NOMINAL_ENTRIES),
-      new Text("Sum"),
-      new BytesWritable(sketch2.compact().toByteArray()))
-    );
-
-    Object result = eval.terminate(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof BytesWritable);
-    Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-    SketchIterator<DoubleSummary> it = resultSketch.iterator();
-    while (it.next()) {
-      Assert.assertEquals(it.getSummary().getValue(), 3.0);
+    try (GenericUDAFEvaluator eval = new DataToDoubleSummaryWithModeSketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.FINAL, new ObjectInspector[] {structInspector});
+      checkFinalResultInspector(resultInspector);
+  
+      @SuppressWarnings("unchecked")
+      State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
+  
+      UpdatableSketch<Double, DoubleSummary> sketch1 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
+      sketch1.update(1, 1.0);
+      sketch1.update(2, 2.0);
+      eval.merge(state, Arrays.asList(
+        new IntWritable(DEFAULT_NOMINAL_ENTRIES),
+        new Text("Sum"),
+        new BytesWritable(sketch1.compact().toByteArray()))
+      );
+  
+      UpdatableSketch<Double, DoubleSummary> sketch2 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
+      sketch2.update(1, 2.0);
+      sketch2.update(2, 1.0);
+      eval.merge(state, Arrays.asList(
+        new IntWritable(DEFAULT_NOMINAL_ENTRIES),
+        new Text("Sum"),
+        new BytesWritable(sketch2.compact().toByteArray()))
+      );
+  
+      Object result = eval.terminate(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof BytesWritable);
+      Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+      SketchIterator<DoubleSummary> it = resultSketch.iterator();
+      while (it.next()) {
+        Assert.assertEquals(it.getSummary().getValue(), 3.0);
+      }
     }
-
-    eval.close();
   }
 
   // COMPLETE mode (single mode, alternative to MapReduce): iterate + terminate
@@ -293,32 +289,31 @@
   public void completeModeIntKeysDefaultParams() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { intInspector, doubleInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new DataToDoubleSummaryWithModeSketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
-    checkFinalResultInspector(resultInspector);
-
-    @SuppressWarnings("unchecked")
-    State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
-    eval.iterate(state, new Object[] {new IntWritable(1), new DoubleWritable(1)});
-    eval.iterate(state, new Object[] {new IntWritable(2), new DoubleWritable(2)});
-    eval.iterate(state, new Object[] {new IntWritable(1), new DoubleWritable(2)});
-    eval.iterate(state, new Object[] {new IntWritable(2), new DoubleWritable(1)});
-
-    Object result = eval.terminate(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof BytesWritable);
-    Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-    SketchIterator<DoubleSummary> it = resultSketch.iterator();
-    while (it.next()) {
-      Assert.assertEquals(it.getSummary().getValue(), 3.0);
+    try (GenericUDAFEvaluator eval = new DataToDoubleSummaryWithModeSketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
+      checkFinalResultInspector(resultInspector);
+  
+      @SuppressWarnings("unchecked")
+      State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
+      eval.iterate(state, new Object[] {new IntWritable(1), new DoubleWritable(1)});
+      eval.iterate(state, new Object[] {new IntWritable(2), new DoubleWritable(2)});
+      eval.iterate(state, new Object[] {new IntWritable(1), new DoubleWritable(2)});
+      eval.iterate(state, new Object[] {new IntWritable(2), new DoubleWritable(1)});
+  
+      Object result = eval.terminate(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof BytesWritable);
+      Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+      SketchIterator<DoubleSummary> it = resultSketch.iterator();
+      while (it.next()) {
+        Assert.assertEquals(it.getSummary().getValue(), 3.0);
+      }
+  
+      eval.reset(state);
+      result = eval.terminate(state);
+      Assert.assertNull(result);
     }
-
-    eval.reset(state);
-    result = eval.terminate(state);
-    Assert.assertNull(result);
-
-    eval.close();
   }
 
   // COMPLETE mode (single mode, alternative to MapReduce): iterate + terminate
@@ -326,62 +321,60 @@
   public void completeModeDoubleKeysExplicitParams() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { doubleInspector, doubleInspector, intInspector, floatInspector, stringInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new DataToDoubleSummaryWithModeSketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
-    checkFinalResultInspector(resultInspector);
-
-    @SuppressWarnings("unchecked")
-    State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
-    eval.iterate(state, new Object[] {new DoubleWritable(1), new DoubleWritable(1), new IntWritable(32), new FloatWritable(0.99f), new Text("Max")});
-    eval.iterate(state, new Object[] {new DoubleWritable(2), new DoubleWritable(2), new IntWritable(32), new FloatWritable(0.99f), new Text("Max")});
-    eval.iterate(state, new Object[] {new DoubleWritable(1), new DoubleWritable(2), new IntWritable(32), new FloatWritable(0.99f), new Text("Max")});
-    eval.iterate(state, new Object[] {new DoubleWritable(2), new DoubleWritable(1), new IntWritable(32), new FloatWritable(0.99f), new Text("Max")});
-
-    Object result = eval.terminate(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof BytesWritable);
-    Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
-    // because of sampling probability < 1
-    Assert.assertTrue(resultSketch.isEstimationMode());
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0, 0.05);
-    SketchIterator<DoubleSummary> it = resultSketch.iterator();
-    while (it.next()) {
-      Assert.assertEquals(it.getSummary().getValue(), 2.0);
+    try (GenericUDAFEvaluator eval = new DataToDoubleSummaryWithModeSketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
+      checkFinalResultInspector(resultInspector);
+  
+      @SuppressWarnings("unchecked")
+      State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
+      eval.iterate(state, new Object[] {new DoubleWritable(1), new DoubleWritable(1), new IntWritable(32), new FloatWritable(0.99f), new Text("Max")});
+      eval.iterate(state, new Object[] {new DoubleWritable(2), new DoubleWritable(2), new IntWritable(32), new FloatWritable(0.99f), new Text("Max")});
+      eval.iterate(state, new Object[] {new DoubleWritable(1), new DoubleWritable(2), new IntWritable(32), new FloatWritable(0.99f), new Text("Max")});
+      eval.iterate(state, new Object[] {new DoubleWritable(2), new DoubleWritable(1), new IntWritable(32), new FloatWritable(0.99f), new Text("Max")});
+  
+      Object result = eval.terminate(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof BytesWritable);
+      Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
+      // because of sampling probability < 1
+      Assert.assertTrue(resultSketch.isEstimationMode());
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0, 0.05);
+      SketchIterator<DoubleSummary> it = resultSketch.iterator();
+      while (it.next()) {
+        Assert.assertEquals(it.getSummary().getValue(), 2.0);
+      }
+  
+      eval.reset(state);
+      result = eval.terminate(state);
+      Assert.assertNull(result);
     }
-
-    eval.reset(state);
-    result = eval.terminate(state);
-    Assert.assertNull(result);
-
-    eval.close();
   }
 
   @Test
   public void completeModeCheckTrimmingToNominal() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { intInspector, doubleInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new DataToDoubleSummaryWithModeSketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
-    checkFinalResultInspector(resultInspector);
-
-    @SuppressWarnings("unchecked")
-    State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
-    for (int i = 0; i < 10000; i++) {
-      eval.iterate(state, new Object[] {new IntWritable(i), new DoubleWritable(1)});
+    try (GenericUDAFEvaluator eval = new DataToDoubleSummaryWithModeSketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
+      checkFinalResultInspector(resultInspector);
+  
+      @SuppressWarnings("unchecked")
+      State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
+      for (int i = 0; i < 10000; i++) {
+        eval.iterate(state, new Object[] {new IntWritable(i), new DoubleWritable(1)});
+      }
+  
+      Object result = eval.terminate(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof BytesWritable);
+      Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 10000.0, 10000 * 0.03);
+      Assert.assertTrue(resultSketch.getRetainedEntries() <= 4096, "retained entries: " + resultSketch.getRetainedEntries());
+  
+      eval.reset(state);
+      result = eval.terminate(state);
+      Assert.assertNull(result);
     }
-
-    Object result = eval.terminate(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof BytesWritable);
-    Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 10000.0, 10000 * 0.03);
-    Assert.assertTrue(resultSketch.getRetainedEntries() <= 4096, "retained entries: " + resultSketch.getRetainedEntries());
-
-    eval.reset(state);
-    result = eval.terminate(state);
-    Assert.assertNull(result);
-
-    eval.close();
   }
 
   static void checkIntermediateResultInspector(ObjectInspector resultInspector) {
diff --git a/src/test/java/com/yahoo/sketches/hive/tuple/UnionArrayOfDoublesSketchUDAFTest.java b/src/test/java/com/yahoo/sketches/hive/tuple/UnionArrayOfDoublesSketchUDAFTest.java
index 378f95f..b330e62 100644
--- a/src/test/java/com/yahoo/sketches/hive/tuple/UnionArrayOfDoublesSketchUDAFTest.java
+++ b/src/test/java/com/yahoo/sketches/hive/tuple/UnionArrayOfDoublesSketchUDAFTest.java
@@ -109,68 +109,66 @@
   public void partial1ModeDefaultParams() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { binaryInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new UnionArrayOfDoublesSketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.PARTIAL1, inspectors);
-    DataToArrayOfDoublesSketchUDAFTest.checkIntermediateResultInspector(resultInspector);
-
-    ArrayOfDoublesState state = (ArrayOfDoublesState) eval.getNewAggregationBuffer();
-
-    ArrayOfDoublesUpdatableSketch sketch1 = new ArrayOfDoublesUpdatableSketchBuilder().build();
-    sketch1.update(1, new double[] {1});
-    eval.iterate(state, new Object[] {new BytesWritable(sketch1.compact().toByteArray())});
-
-    ArrayOfDoublesUpdatableSketch sketch2 = new ArrayOfDoublesUpdatableSketchBuilder().build();
-    sketch2.update(2, new double[] {1});
-    eval.iterate(state, new Object[] {new BytesWritable(sketch2.compact().toByteArray())});
-
-    Object result = eval.terminatePartial(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof List);
-    List<?> r = (List<?>) result;
-    Assert.assertEquals(r.size(), 3);
-    Assert.assertEquals(((IntWritable) (r.get(0))).get(), DEFAULT_NOMINAL_ENTRIES);
-    Assert.assertEquals(((IntWritable) (r.get(1))).get(), 1);
-    ArrayOfDoublesSketch resultSketch = ArrayOfDoublesSketches.wrapSketch(Memory.wrap(((BytesWritable) (r.get(2))).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-
-    eval.close();
+    try (GenericUDAFEvaluator eval = new UnionArrayOfDoublesSketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.PARTIAL1, inspectors);
+      DataToArrayOfDoublesSketchUDAFTest.checkIntermediateResultInspector(resultInspector);
+  
+      ArrayOfDoublesState state = (ArrayOfDoublesState) eval.getNewAggregationBuffer();
+  
+      ArrayOfDoublesUpdatableSketch sketch1 = new ArrayOfDoublesUpdatableSketchBuilder().build();
+      sketch1.update(1, new double[] {1});
+      eval.iterate(state, new Object[] {new BytesWritable(sketch1.compact().toByteArray())});
+  
+      ArrayOfDoublesUpdatableSketch sketch2 = new ArrayOfDoublesUpdatableSketchBuilder().build();
+      sketch2.update(2, new double[] {1});
+      eval.iterate(state, new Object[] {new BytesWritable(sketch2.compact().toByteArray())});
+  
+      Object result = eval.terminatePartial(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof List);
+      List<?> r = (List<?>) result;
+      Assert.assertEquals(r.size(), 3);
+      Assert.assertEquals(((IntWritable) (r.get(0))).get(), DEFAULT_NOMINAL_ENTRIES);
+      Assert.assertEquals(((IntWritable) (r.get(1))).get(), 1);
+      ArrayOfDoublesSketch resultSketch = ArrayOfDoublesSketches.wrapSketch(Memory.wrap(((BytesWritable) (r.get(2))).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+    }
   }
 
   @Test
   public void partial1ModeExplicitParams() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { binaryInspector, intInspector, intInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new UnionArrayOfDoublesSketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.PARTIAL1, inspectors);
-    DataToArrayOfDoublesSketchUDAFTest.checkIntermediateResultInspector(resultInspector);
-
-    final int nomNumEntries = 8;
-    final int numValues = 2;
-    ArrayOfDoublesState state = (ArrayOfDoublesState) eval.getNewAggregationBuffer();
-
-    ArrayOfDoublesUpdatableSketch sketch1 = new ArrayOfDoublesUpdatableSketchBuilder()
-        .setNominalEntries(nomNumEntries).setNumberOfValues(numValues).build();
-    sketch1.update(1, new double[] {1, 2});
-    eval.iterate(state, new Object[] {new BytesWritable(sketch1.compact().toByteArray()),
-        new IntWritable(nomNumEntries), new IntWritable(numValues)});
-
-    ArrayOfDoublesUpdatableSketch sketch2 = new ArrayOfDoublesUpdatableSketchBuilder()
-        .setNominalEntries(nomNumEntries).setNumberOfValues(numValues).build();
-    sketch2.update(2, new double[] {1, 2});
-    eval.iterate(state, new Object[] {new BytesWritable(sketch2.compact().toByteArray()),
-        new IntWritable(nomNumEntries), new IntWritable(numValues)});
-
-    Object result = eval.terminatePartial(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof List);
-    List<?> r = (List<?>) result;
-    Assert.assertEquals(r.size(), 3);
-    Assert.assertEquals(((IntWritable) (r.get(0))).get(), nomNumEntries);
-    Assert.assertEquals(((IntWritable) (r.get(1))).get(), numValues);
-    ArrayOfDoublesSketch resultSketch = ArrayOfDoublesSketches.wrapSketch(Memory.wrap(((BytesWritable) (r.get(2))).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-
-    eval.close();
+    try (GenericUDAFEvaluator eval = new UnionArrayOfDoublesSketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.PARTIAL1, inspectors);
+      DataToArrayOfDoublesSketchUDAFTest.checkIntermediateResultInspector(resultInspector);
+  
+      final int nomNumEntries = 8;
+      final int numValues = 2;
+      ArrayOfDoublesState state = (ArrayOfDoublesState) eval.getNewAggregationBuffer();
+  
+      ArrayOfDoublesUpdatableSketch sketch1 = new ArrayOfDoublesUpdatableSketchBuilder()
+          .setNominalEntries(nomNumEntries).setNumberOfValues(numValues).build();
+      sketch1.update(1, new double[] {1, 2});
+      eval.iterate(state, new Object[] {new BytesWritable(sketch1.compact().toByteArray()),
+          new IntWritable(nomNumEntries), new IntWritable(numValues)});
+  
+      ArrayOfDoublesUpdatableSketch sketch2 = new ArrayOfDoublesUpdatableSketchBuilder()
+          .setNominalEntries(nomNumEntries).setNumberOfValues(numValues).build();
+      sketch2.update(2, new double[] {1, 2});
+      eval.iterate(state, new Object[] {new BytesWritable(sketch2.compact().toByteArray()),
+          new IntWritable(nomNumEntries), new IntWritable(numValues)});
+  
+      Object result = eval.terminatePartial(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof List);
+      List<?> r = (List<?>) result;
+      Assert.assertEquals(r.size(), 3);
+      Assert.assertEquals(((IntWritable) (r.get(0))).get(), nomNumEntries);
+      Assert.assertEquals(((IntWritable) (r.get(1))).get(), numValues);
+      ArrayOfDoublesSketch resultSketch = ArrayOfDoublesSketches.wrapSketch(Memory.wrap(((BytesWritable) (r.get(2))).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+    }
   }
 
   // PARTIAL2 mode (Combine phase in Map-Reduce): merge + terminatePartial
@@ -178,43 +176,42 @@
   public void partial2Mode() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { binaryInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new UnionArrayOfDoublesSketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.PARTIAL2, new ObjectInspector[] {structInspector});
-    DataToArrayOfDoublesSketchUDAFTest.checkIntermediateResultInspector(resultInspector);
-
-    ArrayOfDoublesState state = (ArrayOfDoublesState) eval.getNewAggregationBuffer();
-
-    ArrayOfDoublesUpdatableSketch sketch1 = new ArrayOfDoublesUpdatableSketchBuilder().build();
-    sketch1.update(1, new double[] {1});
-    eval.merge(state, Arrays.asList(
-      new IntWritable(DEFAULT_NOMINAL_ENTRIES),
-      new IntWritable(1),
-      new BytesWritable(sketch1.compact().toByteArray()))
-    );
-
-    ArrayOfDoublesUpdatableSketch sketch2 = new ArrayOfDoublesUpdatableSketchBuilder().build();
-    sketch2.update(2, new double[] {1});
-    eval.merge(state, Arrays.asList(
-      new IntWritable(DEFAULT_NOMINAL_ENTRIES),
-      new IntWritable(1),
-      new BytesWritable(sketch2.compact().toByteArray()))
-    );
-
-    Object result = eval.terminatePartial(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof List);
-    List<?> r = (List<?>) result;
-    Assert.assertEquals(r.size(), 3);
-    Assert.assertEquals(((IntWritable) (r.get(0))).get(), DEFAULT_NOMINAL_ENTRIES);
-    Assert.assertEquals(((IntWritable) (r.get(1))).get(), 1);
-    ArrayOfDoublesSketch resultSketch = ArrayOfDoublesSketches.wrapSketch(Memory.wrap(((BytesWritable) (r.get(2))).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-
-    eval.reset(state);
-    result = eval.terminate(state);
-    Assert.assertNull(result);
-
-    eval.close();
+    try (GenericUDAFEvaluator eval = new UnionArrayOfDoublesSketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.PARTIAL2, new ObjectInspector[] {structInspector});
+      DataToArrayOfDoublesSketchUDAFTest.checkIntermediateResultInspector(resultInspector);
+  
+      ArrayOfDoublesState state = (ArrayOfDoublesState) eval.getNewAggregationBuffer();
+  
+      ArrayOfDoublesUpdatableSketch sketch1 = new ArrayOfDoublesUpdatableSketchBuilder().build();
+      sketch1.update(1, new double[] {1});
+      eval.merge(state, Arrays.asList(
+        new IntWritable(DEFAULT_NOMINAL_ENTRIES),
+        new IntWritable(1),
+        new BytesWritable(sketch1.compact().toByteArray()))
+      );
+  
+      ArrayOfDoublesUpdatableSketch sketch2 = new ArrayOfDoublesUpdatableSketchBuilder().build();
+      sketch2.update(2, new double[] {1});
+      eval.merge(state, Arrays.asList(
+        new IntWritable(DEFAULT_NOMINAL_ENTRIES),
+        new IntWritable(1),
+        new BytesWritable(sketch2.compact().toByteArray()))
+      );
+  
+      Object result = eval.terminatePartial(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof List);
+      List<?> r = (List<?>) result;
+      Assert.assertEquals(r.size(), 3);
+      Assert.assertEquals(((IntWritable) (r.get(0))).get(), DEFAULT_NOMINAL_ENTRIES);
+      Assert.assertEquals(((IntWritable) (r.get(1))).get(), 1);
+      ArrayOfDoublesSketch resultSketch = ArrayOfDoublesSketches.wrapSketch(Memory.wrap(((BytesWritable) (r.get(2))).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+  
+      eval.reset(state);
+      result = eval.terminate(state);
+      Assert.assertNull(result);
+    }
   }
 
   // FINAL mode (Reduce phase in Map-Reduce): merge + terminate
@@ -222,35 +219,34 @@
   public void finalMode() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { binaryInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new UnionArrayOfDoublesSketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.FINAL, new ObjectInspector[] {structInspector});
-    DataToArrayOfDoublesSketchUDAFTest.checkFinalResultInspector(resultInspector);
-
-    ArrayOfDoublesState state = (ArrayOfDoublesState) eval.getNewAggregationBuffer();
-
-    ArrayOfDoublesUpdatableSketch sketch1 = new ArrayOfDoublesUpdatableSketchBuilder().build();
-    sketch1.update(1, new double[] {1});
-    eval.merge(state, Arrays.asList(
-      new IntWritable(DEFAULT_NOMINAL_ENTRIES),
-      new IntWritable(1),
-      new BytesWritable(sketch1.compact().toByteArray()))
-    );
-
-    ArrayOfDoublesUpdatableSketch sketch2 = new ArrayOfDoublesUpdatableSketchBuilder().build();
-    sketch2.update(2, new double[] {1});
-    eval.merge(state, Arrays.asList(
-      new IntWritable(DEFAULT_NOMINAL_ENTRIES),
-      new IntWritable(1),
-      new BytesWritable(sketch2.compact().toByteArray()))
-    );
-
-    Object result = eval.terminate(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof BytesWritable);
-    ArrayOfDoublesSketch resultSketch = ArrayOfDoublesSketches.wrapSketch(Memory.wrap(((BytesWritable) result).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-
-    eval.close();
+    try (GenericUDAFEvaluator eval = new UnionArrayOfDoublesSketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.FINAL, new ObjectInspector[] {structInspector});
+      DataToArrayOfDoublesSketchUDAFTest.checkFinalResultInspector(resultInspector);
+  
+      ArrayOfDoublesState state = (ArrayOfDoublesState) eval.getNewAggregationBuffer();
+  
+      ArrayOfDoublesUpdatableSketch sketch1 = new ArrayOfDoublesUpdatableSketchBuilder().build();
+      sketch1.update(1, new double[] {1});
+      eval.merge(state, Arrays.asList(
+        new IntWritable(DEFAULT_NOMINAL_ENTRIES),
+        new IntWritable(1),
+        new BytesWritable(sketch1.compact().toByteArray()))
+      );
+  
+      ArrayOfDoublesUpdatableSketch sketch2 = new ArrayOfDoublesUpdatableSketchBuilder().build();
+      sketch2.update(2, new double[] {1});
+      eval.merge(state, Arrays.asList(
+        new IntWritable(DEFAULT_NOMINAL_ENTRIES),
+        new IntWritable(1),
+        new BytesWritable(sketch2.compact().toByteArray()))
+      );
+  
+      Object result = eval.terminate(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof BytesWritable);
+      ArrayOfDoublesSketch resultSketch = ArrayOfDoublesSketches.wrapSketch(Memory.wrap(((BytesWritable) result).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+    }
   }
 
   // COMPLETE mode (single mode, alternative to MapReduce): iterate + terminate
@@ -258,68 +254,66 @@
   public void completeModeDefaultParams() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { binaryInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new UnionArrayOfDoublesSketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
-    DataToArrayOfDoublesSketchUDAFTest.checkFinalResultInspector(resultInspector);
-
-    ArrayOfDoublesState state = (ArrayOfDoublesState) eval.getNewAggregationBuffer();
-
-    ArrayOfDoublesUpdatableSketch sketch1 = new ArrayOfDoublesUpdatableSketchBuilder().build();
-    sketch1.update(1, new double[] {1});
-    eval.iterate(state, new Object[] {new BytesWritable(sketch1.compact().toByteArray())});
-
-    ArrayOfDoublesUpdatableSketch sketch2 = new ArrayOfDoublesUpdatableSketchBuilder().build();
-    sketch2.update(2, new double[] {1});
-    eval.iterate(state, new Object[] {new BytesWritable(sketch2.compact().toByteArray())});
-
-    Object result = eval.terminate(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof BytesWritable);
-    ArrayOfDoublesSketch resultSketch = ArrayOfDoublesSketches.wrapSketch(Memory.wrap(((BytesWritable) result).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-
-    eval.reset(state);
-    result = eval.terminate(state);
-    Assert.assertNull(result);
-
-    eval.close();
+    try (GenericUDAFEvaluator eval = new UnionArrayOfDoublesSketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
+      DataToArrayOfDoublesSketchUDAFTest.checkFinalResultInspector(resultInspector);
+  
+      ArrayOfDoublesState state = (ArrayOfDoublesState) eval.getNewAggregationBuffer();
+  
+      ArrayOfDoublesUpdatableSketch sketch1 = new ArrayOfDoublesUpdatableSketchBuilder().build();
+      sketch1.update(1, new double[] {1});
+      eval.iterate(state, new Object[] {new BytesWritable(sketch1.compact().toByteArray())});
+  
+      ArrayOfDoublesUpdatableSketch sketch2 = new ArrayOfDoublesUpdatableSketchBuilder().build();
+      sketch2.update(2, new double[] {1});
+      eval.iterate(state, new Object[] {new BytesWritable(sketch2.compact().toByteArray())});
+  
+      Object result = eval.terminate(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof BytesWritable);
+      ArrayOfDoublesSketch resultSketch = ArrayOfDoublesSketches.wrapSketch(Memory.wrap(((BytesWritable) result).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+  
+      eval.reset(state);
+      result = eval.terminate(state);
+      Assert.assertNull(result);
+    }
   }
 
   @Test
   public void completeModeExplicitParams() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { binaryInspector, intInspector, intInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new UnionArrayOfDoublesSketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
-    DataToArrayOfDoublesSketchUDAFTest.checkFinalResultInspector(resultInspector);
-
-    final int nomNumEntries = 8;
-    final int numValues = 2;
-    ArrayOfDoublesState state = (ArrayOfDoublesState) eval.getNewAggregationBuffer();
-
-    ArrayOfDoublesUpdatableSketch sketch1 = new ArrayOfDoublesUpdatableSketchBuilder()
-        .setNominalEntries(nomNumEntries).setNumberOfValues(numValues).build();
-    sketch1.update(1, new double[] {1, 2});
-    eval.iterate(state, new Object[] {new BytesWritable(sketch1.compact().toByteArray()),
-        new IntWritable(nomNumEntries), new IntWritable(numValues)});
-
-    ArrayOfDoublesUpdatableSketch sketch2 = new ArrayOfDoublesUpdatableSketchBuilder()
-        .setNominalEntries(nomNumEntries).setNumberOfValues(numValues).build();
-    sketch2.update(2, new double[] {1, 2});
-    eval.iterate(state, new Object[] {new BytesWritable(sketch2.compact().toByteArray()),
-        new IntWritable(nomNumEntries), new IntWritable(numValues)});
-
-    Object result = eval.terminate(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof BytesWritable);
-    ArrayOfDoublesSketch resultSketch = ArrayOfDoublesSketches.wrapSketch(Memory.wrap(((BytesWritable) result).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-
-    eval.reset(state);
-    result = eval.terminate(state);
-    Assert.assertNull(result);
-
-    eval.close();
+    try (GenericUDAFEvaluator eval = new UnionArrayOfDoublesSketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
+      DataToArrayOfDoublesSketchUDAFTest.checkFinalResultInspector(resultInspector);
+  
+      final int nomNumEntries = 8;
+      final int numValues = 2;
+      ArrayOfDoublesState state = (ArrayOfDoublesState) eval.getNewAggregationBuffer();
+  
+      ArrayOfDoublesUpdatableSketch sketch1 = new ArrayOfDoublesUpdatableSketchBuilder()
+          .setNominalEntries(nomNumEntries).setNumberOfValues(numValues).build();
+      sketch1.update(1, new double[] {1, 2});
+      eval.iterate(state, new Object[] {new BytesWritable(sketch1.compact().toByteArray()),
+          new IntWritable(nomNumEntries), new IntWritable(numValues)});
+  
+      ArrayOfDoublesUpdatableSketch sketch2 = new ArrayOfDoublesUpdatableSketchBuilder()
+          .setNominalEntries(nomNumEntries).setNumberOfValues(numValues).build();
+      sketch2.update(2, new double[] {1, 2});
+      eval.iterate(state, new Object[] {new BytesWritable(sketch2.compact().toByteArray()),
+          new IntWritable(nomNumEntries), new IntWritable(numValues)});
+  
+      Object result = eval.terminate(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof BytesWritable);
+      ArrayOfDoublesSketch resultSketch = ArrayOfDoublesSketches.wrapSketch(Memory.wrap(((BytesWritable) result).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+  
+      eval.reset(state);
+      result = eval.terminate(state);
+      Assert.assertNull(result);
+    }
   }
 
 }
diff --git a/src/test/java/com/yahoo/sketches/hive/tuple/UnionDoubleSummarySketchUDAFTest.java b/src/test/java/com/yahoo/sketches/hive/tuple/UnionDoubleSummarySketchUDAFTest.java
index 14f4509..825ccb2 100644
--- a/src/test/java/com/yahoo/sketches/hive/tuple/UnionDoubleSummarySketchUDAFTest.java
+++ b/src/test/java/com/yahoo/sketches/hive/tuple/UnionDoubleSummarySketchUDAFTest.java
@@ -97,67 +97,65 @@
   public void partial1ModeDefaultParams() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { binaryInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new UnionDoubleSummarySketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.PARTIAL1, inspectors);
-    DataToDoubleSummarySketchUDAFTest.checkIntermediateResultInspector(resultInspector);
-
-    @SuppressWarnings("unchecked")
-    State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
-
-    UpdatableSketch<Double, DoubleSummary> sketch1 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
-    sketch1.update(1, 1.0);
-    eval.iterate(state, new Object[] {new BytesWritable(sketch1.compact().toByteArray())});
-
-    UpdatableSketch<Double, DoubleSummary> sketch2 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
-    sketch2.update(2, 1.0);
-    eval.iterate(state, new Object[] {new BytesWritable(sketch2.compact().toByteArray())});
-
-    Object result = eval.terminatePartial(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof List);
-    List<?> r = (List<?>) result;
-    Assert.assertEquals(r.size(), 2);
-    Assert.assertEquals(((IntWritable) (r.get(0))).get(), DEFAULT_NOMINAL_ENTRIES);
-    Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) (r.get(1))).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-
-    eval.close();
+    try (GenericUDAFEvaluator eval = new UnionDoubleSummarySketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.PARTIAL1, inspectors);
+      DataToDoubleSummarySketchUDAFTest.checkIntermediateResultInspector(resultInspector);
+  
+      @SuppressWarnings("unchecked")
+      State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
+  
+      UpdatableSketch<Double, DoubleSummary> sketch1 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
+      sketch1.update(1, 1.0);
+      eval.iterate(state, new Object[] {new BytesWritable(sketch1.compact().toByteArray())});
+  
+      UpdatableSketch<Double, DoubleSummary> sketch2 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
+      sketch2.update(2, 1.0);
+      eval.iterate(state, new Object[] {new BytesWritable(sketch2.compact().toByteArray())});
+  
+      Object result = eval.terminatePartial(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof List);
+      List<?> r = (List<?>) result;
+      Assert.assertEquals(r.size(), 2);
+      Assert.assertEquals(((IntWritable) (r.get(0))).get(), DEFAULT_NOMINAL_ENTRIES);
+      Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) (r.get(1))).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+    }
   }
 
   @Test
   public void partial1ModeExplicitParams() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { binaryInspector, intInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new UnionDoubleSummarySketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.PARTIAL1, inspectors);
-    DataToDoubleSummarySketchUDAFTest.checkIntermediateResultInspector(resultInspector);
-
-    final int nomNumEntries = 8;
-    @SuppressWarnings("unchecked")
-    State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
-
-    UpdatableSketch<Double, DoubleSummary> sketch1 =
-        new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).setNominalEntries(nomNumEntries).build();
-    sketch1.update(1, 1.0);
-    eval.iterate(state, new Object[] {new BytesWritable(sketch1.compact().toByteArray()),
-        new IntWritable(nomNumEntries)});
-
-    UpdatableSketch<Double, DoubleSummary> sketch2 =
-        new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).setNominalEntries(nomNumEntries).build();
-    sketch2.update(2, 1.0);
-    eval.iterate(state, new Object[] {new BytesWritable(sketch2.compact().toByteArray()),
-        new IntWritable(nomNumEntries)});
-
-    Object result = eval.terminatePartial(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof List);
-    List<?> r = (List<?>) result;
-    Assert.assertEquals(r.size(), 2);
-    Assert.assertEquals(((IntWritable) (r.get(0))).get(), nomNumEntries);
-    Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) (r.get(1))).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-
-    eval.close();
+    try (GenericUDAFEvaluator eval = new UnionDoubleSummarySketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.PARTIAL1, inspectors);
+      DataToDoubleSummarySketchUDAFTest.checkIntermediateResultInspector(resultInspector);
+  
+      final int nomNumEntries = 8;
+      @SuppressWarnings("unchecked")
+      State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
+  
+      UpdatableSketch<Double, DoubleSummary> sketch1 =
+          new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).setNominalEntries(nomNumEntries).build();
+      sketch1.update(1, 1.0);
+      eval.iterate(state, new Object[] {new BytesWritable(sketch1.compact().toByteArray()),
+          new IntWritable(nomNumEntries)});
+  
+      UpdatableSketch<Double, DoubleSummary> sketch2 =
+          new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).setNominalEntries(nomNumEntries).build();
+      sketch2.update(2, 1.0);
+      eval.iterate(state, new Object[] {new BytesWritable(sketch2.compact().toByteArray()),
+          new IntWritable(nomNumEntries)});
+  
+      Object result = eval.terminatePartial(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof List);
+      List<?> r = (List<?>) result;
+      Assert.assertEquals(r.size(), 2);
+      Assert.assertEquals(((IntWritable) (r.get(0))).get(), nomNumEntries);
+      Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) (r.get(1))).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+    }
   }
 
   // PARTIAL2 mode (Combine phase in Map-Reduce): merge + terminatePartial
@@ -165,41 +163,40 @@
   public void partial2Mode() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { binaryInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new UnionDoubleSummarySketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.PARTIAL2, new ObjectInspector[] {structInspector});
-    DataToDoubleSummarySketchUDAFTest.checkIntermediateResultInspector(resultInspector);
-
-    @SuppressWarnings("unchecked")
-    State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
-
-    UpdatableSketch<Double, DoubleSummary> sketch1 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
-    sketch1.update(1, 1.0);
-    eval.merge(state, Arrays.asList(
-      new IntWritable(DEFAULT_NOMINAL_ENTRIES),
-      new BytesWritable(sketch1.compact().toByteArray()))
-    );
-
-    UpdatableSketch<Double, DoubleSummary> sketch2 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
-    sketch2.update(2, 1.0);
-    eval.merge(state, Arrays.asList(
-      new IntWritable(DEFAULT_NOMINAL_ENTRIES),
-      new BytesWritable(sketch2.compact().toByteArray()))
-    );
-
-    Object result = eval.terminatePartial(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof List);
-    List<?> r = (List<?>) result;
-    Assert.assertEquals(r.size(), 2);
-    Assert.assertEquals(((IntWritable) (r.get(0))).get(), DEFAULT_NOMINAL_ENTRIES);
-    Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) (r.get(1))).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-
-    eval.reset(state);
-    result = eval.terminate(state);
-    Assert.assertNull(result);
-
-    eval.close();
+    try (GenericUDAFEvaluator eval = new UnionDoubleSummarySketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.PARTIAL2, new ObjectInspector[] {structInspector});
+      DataToDoubleSummarySketchUDAFTest.checkIntermediateResultInspector(resultInspector);
+  
+      @SuppressWarnings("unchecked")
+      State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
+  
+      UpdatableSketch<Double, DoubleSummary> sketch1 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
+      sketch1.update(1, 1.0);
+      eval.merge(state, Arrays.asList(
+        new IntWritable(DEFAULT_NOMINAL_ENTRIES),
+        new BytesWritable(sketch1.compact().toByteArray()))
+      );
+  
+      UpdatableSketch<Double, DoubleSummary> sketch2 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
+      sketch2.update(2, 1.0);
+      eval.merge(state, Arrays.asList(
+        new IntWritable(DEFAULT_NOMINAL_ENTRIES),
+        new BytesWritable(sketch2.compact().toByteArray()))
+      );
+  
+      Object result = eval.terminatePartial(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof List);
+      List<?> r = (List<?>) result;
+      Assert.assertEquals(r.size(), 2);
+      Assert.assertEquals(((IntWritable) (r.get(0))).get(), DEFAULT_NOMINAL_ENTRIES);
+      Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) (r.get(1))).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+  
+      eval.reset(state);
+      result = eval.terminate(state);
+      Assert.assertNull(result);
+    }
   }
 
   // FINAL mode (Reduce phase in Map-Reduce): merge + terminate
@@ -207,34 +204,33 @@
   public void finalMode() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { binaryInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new UnionDoubleSummarySketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.FINAL, new ObjectInspector[] {structInspector});
-    DataToDoubleSummarySketchUDAFTest.checkFinalResultInspector(resultInspector);
-
-    @SuppressWarnings("unchecked")
-    State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
-
-    UpdatableSketch<Double, DoubleSummary> sketch1 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
-    sketch1.update(1, 1.0);
-    eval.merge(state, Arrays.asList(
-      new IntWritable(DEFAULT_NOMINAL_ENTRIES),
-      new BytesWritable(sketch1.compact().toByteArray()))
-    );
-
-    UpdatableSketch<Double, DoubleSummary> sketch2 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
-    sketch2.update(2, 1.0);
-    eval.merge(state, Arrays.asList(
-      new IntWritable(DEFAULT_NOMINAL_ENTRIES),
-      new BytesWritable(sketch2.compact().toByteArray()))
-    );
-
-    Object result = eval.terminate(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof BytesWritable);
-    Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-
-    eval.close();
+    try (GenericUDAFEvaluator eval = new UnionDoubleSummarySketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.FINAL, new ObjectInspector[] {structInspector});
+      DataToDoubleSummarySketchUDAFTest.checkFinalResultInspector(resultInspector);
+  
+      @SuppressWarnings("unchecked")
+      State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
+  
+      UpdatableSketch<Double, DoubleSummary> sketch1 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
+      sketch1.update(1, 1.0);
+      eval.merge(state, Arrays.asList(
+        new IntWritable(DEFAULT_NOMINAL_ENTRIES),
+        new BytesWritable(sketch1.compact().toByteArray()))
+      );
+  
+      UpdatableSketch<Double, DoubleSummary> sketch2 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
+      sketch2.update(2, 1.0);
+      eval.merge(state, Arrays.asList(
+        new IntWritable(DEFAULT_NOMINAL_ENTRIES),
+        new BytesWritable(sketch2.compact().toByteArray()))
+      );
+  
+      Object result = eval.terminate(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof BytesWritable);
+      Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+    }
   }
 
   // COMPLETE mode (single mode, alternative to MapReduce): iterate + terminate
@@ -242,69 +238,67 @@
   public void completeModeDefaultParams() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { binaryInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new UnionDoubleSummarySketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
-    DataToDoubleSummarySketchUDAFTest.checkFinalResultInspector(resultInspector);
-
-    @SuppressWarnings("unchecked")
-    State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
-
-    UpdatableSketch<Double, DoubleSummary> sketch1 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
-    sketch1.update(1, 1.0);
-    eval.iterate(state, new Object[] {new BytesWritable(sketch1.compact().toByteArray())});
-
-    UpdatableSketch<Double, DoubleSummary> sketch2 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
-    sketch2.update(2, 1.0);
-    eval.iterate(state, new Object[] {new BytesWritable(sketch2.compact().toByteArray())});
-
-    Object result = eval.terminate(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof BytesWritable);
-    Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-
-    eval.reset(state);
-    result = eval.terminate(state);
-    Assert.assertNull(result);
-
-    eval.close();
+    try (GenericUDAFEvaluator eval = new UnionDoubleSummarySketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
+      DataToDoubleSummarySketchUDAFTest.checkFinalResultInspector(resultInspector);
+  
+      @SuppressWarnings("unchecked")
+      State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
+  
+      UpdatableSketch<Double, DoubleSummary> sketch1 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
+      sketch1.update(1, 1.0);
+      eval.iterate(state, new Object[] {new BytesWritable(sketch1.compact().toByteArray())});
+  
+      UpdatableSketch<Double, DoubleSummary> sketch2 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
+      sketch2.update(2, 1.0);
+      eval.iterate(state, new Object[] {new BytesWritable(sketch2.compact().toByteArray())});
+  
+      Object result = eval.terminate(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof BytesWritable);
+      Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+  
+      eval.reset(state);
+      result = eval.terminate(state);
+      Assert.assertNull(result);
+    }
   }
 
   @Test
   public void completeModeExplicitParams() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { binaryInspector, intInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new UnionDoubleSummarySketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
-    DataToDoubleSummarySketchUDAFTest.checkFinalResultInspector(resultInspector);
-
-    final int nomNumEntries = 8;
-    @SuppressWarnings("unchecked")
-    State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
-
-    UpdatableSketch<Double, DoubleSummary> sketch1 =
-        new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).setNominalEntries(nomNumEntries).build();
-    sketch1.update(1, 1.0);
-    eval.iterate(state, new Object[] {new BytesWritable(sketch1.compact().toByteArray()),
-        new IntWritable(nomNumEntries)});
-
-    UpdatableSketch<Double, DoubleSummary> sketch2 =
-        new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).setNominalEntries(nomNumEntries).build();
-    sketch2.update(2, 1.0);
-    eval.iterate(state, new Object[] {new BytesWritable(sketch2.compact().toByteArray()),
-        new IntWritable(nomNumEntries)});
-
-    Object result = eval.terminate(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof BytesWritable);
-    Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0, 0.05);
-
-    eval.reset(state);
-    result = eval.terminate(state);
-    Assert.assertNull(result);
-
-    eval.close();
+    try (GenericUDAFEvaluator eval = new UnionDoubleSummarySketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
+      DataToDoubleSummarySketchUDAFTest.checkFinalResultInspector(resultInspector);
+  
+      final int nomNumEntries = 8;
+      @SuppressWarnings("unchecked")
+      State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
+  
+      UpdatableSketch<Double, DoubleSummary> sketch1 =
+          new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).setNominalEntries(nomNumEntries).build();
+      sketch1.update(1, 1.0);
+      eval.iterate(state, new Object[] {new BytesWritable(sketch1.compact().toByteArray()),
+          new IntWritable(nomNumEntries)});
+  
+      UpdatableSketch<Double, DoubleSummary> sketch2 =
+          new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).setNominalEntries(nomNumEntries).build();
+      sketch2.update(2, 1.0);
+      eval.iterate(state, new Object[] {new BytesWritable(sketch2.compact().toByteArray()),
+          new IntWritable(nomNumEntries)});
+  
+      Object result = eval.terminate(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof BytesWritable);
+      Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0, 0.05);
+  
+      eval.reset(state);
+      result = eval.terminate(state);
+      Assert.assertNull(result);
+    }
   }
 
 }
diff --git a/src/test/java/com/yahoo/sketches/hive/tuple/UnionDoubleSummaryWithModeSketchUDAFTest.java b/src/test/java/com/yahoo/sketches/hive/tuple/UnionDoubleSummaryWithModeSketchUDAFTest.java
index 75dab50..0605e53 100644
--- a/src/test/java/com/yahoo/sketches/hive/tuple/UnionDoubleSummaryWithModeSketchUDAFTest.java
+++ b/src/test/java/com/yahoo/sketches/hive/tuple/UnionDoubleSummaryWithModeSketchUDAFTest.java
@@ -119,81 +119,79 @@
   public void partial1ModeDefaultParams() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { binaryInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new UnionDoubleSummaryWithModeSketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.PARTIAL1, inspectors);
-    checkIntermediateResultInspector(resultInspector);
-
-    @SuppressWarnings("unchecked")
-    State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
-
-    UpdatableSketch<Double, DoubleSummary> sketch1 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
-    sketch1.update(1, 1.0);
-    sketch1.update(2, 2.0);
-    eval.iterate(state, new Object[] {new BytesWritable(sketch1.compact().toByteArray())});
-
-    UpdatableSketch<Double, DoubleSummary> sketch2 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
-    sketch2.update(1, 2.0);
-    sketch2.update(2, 1.0);
-    eval.iterate(state, new Object[] {new BytesWritable(sketch2.compact().toByteArray())});
-
-    Object result = eval.terminatePartial(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof List);
-    List<?> r = (List<?>) result;
-    Assert.assertEquals(r.size(), 3);
-    Assert.assertEquals(((IntWritable) r.get(0)).get(), DEFAULT_NOMINAL_ENTRIES);
-    Assert.assertEquals(((Text) r.get(1)).toString(), DoubleSummary.Mode.Sum.toString());
-    Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) r.get(2)).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-    SketchIterator<DoubleSummary> it = resultSketch.iterator();
-    while (it.next()) {
-      Assert.assertEquals(it.getSummary().getValue(), 3.0);
+    try (GenericUDAFEvaluator eval = new UnionDoubleSummaryWithModeSketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.PARTIAL1, inspectors);
+      checkIntermediateResultInspector(resultInspector);
+  
+      @SuppressWarnings("unchecked")
+      State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
+  
+      UpdatableSketch<Double, DoubleSummary> sketch1 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
+      sketch1.update(1, 1.0);
+      sketch1.update(2, 2.0);
+      eval.iterate(state, new Object[] {new BytesWritable(sketch1.compact().toByteArray())});
+  
+      UpdatableSketch<Double, DoubleSummary> sketch2 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
+      sketch2.update(1, 2.0);
+      sketch2.update(2, 1.0);
+      eval.iterate(state, new Object[] {new BytesWritable(sketch2.compact().toByteArray())});
+  
+      Object result = eval.terminatePartial(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof List);
+      List<?> r = (List<?>) result;
+      Assert.assertEquals(r.size(), 3);
+      Assert.assertEquals(((IntWritable) r.get(0)).get(), DEFAULT_NOMINAL_ENTRIES);
+      Assert.assertEquals(((Text) r.get(1)).toString(), DoubleSummary.Mode.Sum.toString());
+      Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) r.get(2)).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+      SketchIterator<DoubleSummary> it = resultSketch.iterator();
+      while (it.next()) {
+        Assert.assertEquals(it.getSummary().getValue(), 3.0);
+      }
     }
-
-    eval.close();
   }
 
   @Test
   public void partial1ModeExplicitParams() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { binaryInspector, intInspector, stringInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new UnionDoubleSummaryWithModeSketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.PARTIAL1, inspectors);
-    checkIntermediateResultInspector(resultInspector);
-
-    final int nomNumEntries = 8;
-    @SuppressWarnings("unchecked")
-    State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
-
-    UpdatableSketch<Double, DoubleSummary> sketch1 =
-        new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).setNominalEntries(nomNumEntries).build();
-    sketch1.update(1, 1.0);
-    sketch1.update(2, 2.0);
-    eval.iterate(state, new Object[] {new BytesWritable(sketch1.compact().toByteArray()),
-        new IntWritable(nomNumEntries), new Text("Max")});
-
-    UpdatableSketch<Double, DoubleSummary> sketch2 =
-        new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).setNominalEntries(nomNumEntries).build();
-    sketch2.update(1, 2.0);
-    sketch2.update(2, 1.0);
-    eval.iterate(state, new Object[] {new BytesWritable(sketch2.compact().toByteArray()),
-        new IntWritable(nomNumEntries), new Text("Max")});
-
-    Object result = eval.terminatePartial(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof List);
-    List<?> r = (List<?>) result;
-    Assert.assertEquals(r.size(), 3);
-    Assert.assertEquals(((IntWritable) r.get(0)).get(), nomNumEntries);
-    Assert.assertEquals(((Text) r.get(1)).toString(), DoubleSummary.Mode.Max.toString());
-    Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) r.get(2)).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-    SketchIterator<DoubleSummary> it = resultSketch.iterator();
-    while (it.next()) {
-      Assert.assertEquals(it.getSummary().getValue(), 2.0);
+    try (GenericUDAFEvaluator eval = new UnionDoubleSummaryWithModeSketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.PARTIAL1, inspectors);
+      checkIntermediateResultInspector(resultInspector);
+  
+      final int nomNumEntries = 8;
+      @SuppressWarnings("unchecked")
+      State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
+  
+      UpdatableSketch<Double, DoubleSummary> sketch1 =
+          new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).setNominalEntries(nomNumEntries).build();
+      sketch1.update(1, 1.0);
+      sketch1.update(2, 2.0);
+      eval.iterate(state, new Object[] {new BytesWritable(sketch1.compact().toByteArray()),
+          new IntWritable(nomNumEntries), new Text("Max")});
+  
+      UpdatableSketch<Double, DoubleSummary> sketch2 =
+          new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).setNominalEntries(nomNumEntries).build();
+      sketch2.update(1, 2.0);
+      sketch2.update(2, 1.0);
+      eval.iterate(state, new Object[] {new BytesWritable(sketch2.compact().toByteArray()),
+          new IntWritable(nomNumEntries), new Text("Max")});
+  
+      Object result = eval.terminatePartial(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof List);
+      List<?> r = (List<?>) result;
+      Assert.assertEquals(r.size(), 3);
+      Assert.assertEquals(((IntWritable) r.get(0)).get(), nomNumEntries);
+      Assert.assertEquals(((Text) r.get(1)).toString(), DoubleSummary.Mode.Max.toString());
+      Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) r.get(2)).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+      SketchIterator<DoubleSummary> it = resultSketch.iterator();
+      while (it.next()) {
+        Assert.assertEquals(it.getSummary().getValue(), 2.0);
+      }
     }
-
-    eval.close();
   }
 
   // PARTIAL2 mode (Combine phase in Map-Reduce): merge + terminatePartial
@@ -201,50 +199,49 @@
   public void partial2Mode() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { binaryInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new UnionDoubleSummaryWithModeSketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.PARTIAL2, new ObjectInspector[] {structInspector});
-    checkIntermediateResultInspector(resultInspector);
-
-    @SuppressWarnings("unchecked")
-    State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
-
-    UpdatableSketch<Double, DoubleSummary> sketch1 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
-    sketch1.update(1, 1.0);
-    sketch1.update(2, 2.0);
-    eval.merge(state, Arrays.asList(
-      new IntWritable(DEFAULT_NOMINAL_ENTRIES),
-      new Text("Sum"),
-      new BytesWritable(sketch1.compact().toByteArray()))
-    );
-
-    UpdatableSketch<Double, DoubleSummary> sketch2 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
-    sketch2.update(1, 2.0);
-    sketch2.update(2, 1.0);
-    eval.merge(state, Arrays.asList(
-      new IntWritable(DEFAULT_NOMINAL_ENTRIES),
-      new Text("Sum"),
-      new BytesWritable(sketch2.compact().toByteArray()))
-    );
-
-    Object result = eval.terminatePartial(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof List);
-    List<?> r = (List<?>) result;
-    Assert.assertEquals(r.size(), 3);
-    Assert.assertEquals(((IntWritable) r.get(0)).get(), DEFAULT_NOMINAL_ENTRIES);
-    Assert.assertEquals(((Text) r.get(1)).toString(), DoubleSummary.Mode.Sum.toString());
-    Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) r.get(2)).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-    SketchIterator<DoubleSummary> it = resultSketch.iterator();
-    while (it.next()) {
-      Assert.assertEquals(it.getSummary().getValue(), 3.0);
+    try (GenericUDAFEvaluator eval = new UnionDoubleSummaryWithModeSketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.PARTIAL2, new ObjectInspector[] {structInspector});
+      checkIntermediateResultInspector(resultInspector);
+  
+      @SuppressWarnings("unchecked")
+      State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
+  
+      UpdatableSketch<Double, DoubleSummary> sketch1 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
+      sketch1.update(1, 1.0);
+      sketch1.update(2, 2.0);
+      eval.merge(state, Arrays.asList(
+        new IntWritable(DEFAULT_NOMINAL_ENTRIES),
+        new Text("Sum"),
+        new BytesWritable(sketch1.compact().toByteArray()))
+      );
+  
+      UpdatableSketch<Double, DoubleSummary> sketch2 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
+      sketch2.update(1, 2.0);
+      sketch2.update(2, 1.0);
+      eval.merge(state, Arrays.asList(
+        new IntWritable(DEFAULT_NOMINAL_ENTRIES),
+        new Text("Sum"),
+        new BytesWritable(sketch2.compact().toByteArray()))
+      );
+  
+      Object result = eval.terminatePartial(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof List);
+      List<?> r = (List<?>) result;
+      Assert.assertEquals(r.size(), 3);
+      Assert.assertEquals(((IntWritable) r.get(0)).get(), DEFAULT_NOMINAL_ENTRIES);
+      Assert.assertEquals(((Text) r.get(1)).toString(), DoubleSummary.Mode.Sum.toString());
+      Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) r.get(2)).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+      SketchIterator<DoubleSummary> it = resultSketch.iterator();
+      while (it.next()) {
+        Assert.assertEquals(it.getSummary().getValue(), 3.0);
+      }
+  
+      eval.reset(state);
+      result = eval.terminate(state);
+      Assert.assertNull(result);
     }
-
-    eval.reset(state);
-    result = eval.terminate(state);
-    Assert.assertNull(result);
-
-    eval.close();
   }
 
   // FINAL mode (Reduce phase in Map-Reduce): merge + terminate
@@ -252,42 +249,41 @@
   public void finalMode() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { binaryInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new UnionDoubleSummaryWithModeSketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.FINAL, new ObjectInspector[] {structInspector});
-    DataToDoubleSummarySketchUDAFTest.checkFinalResultInspector(resultInspector);
-
-    @SuppressWarnings("unchecked")
-    State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
-
-    UpdatableSketch<Double, DoubleSummary> sketch1 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
-    sketch1.update(1, 1.0);
-    sketch1.update(2, 2.0);
-    eval.merge(state, Arrays.asList(
-      new IntWritable(DEFAULT_NOMINAL_ENTRIES),
-      new Text("Min"),
-      new BytesWritable(sketch1.compact().toByteArray()))
-    );
-
-    UpdatableSketch<Double, DoubleSummary> sketch2 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
-    sketch2.update(1, 2.0);
-    sketch2.update(2, 1.0);
-    eval.merge(state, Arrays.asList(
-      new IntWritable(DEFAULT_NOMINAL_ENTRIES),
-      new Text("Min"),
-      new BytesWritable(sketch2.compact().toByteArray()))
-    );
-
-    Object result = eval.terminate(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof BytesWritable);
-    Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-    SketchIterator<DoubleSummary> it = resultSketch.iterator();
-    while (it.next()) {
-      Assert.assertEquals(it.getSummary().getValue(), 1.0);
+    try (GenericUDAFEvaluator eval = new UnionDoubleSummaryWithModeSketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.FINAL, new ObjectInspector[] {structInspector});
+      DataToDoubleSummarySketchUDAFTest.checkFinalResultInspector(resultInspector);
+  
+      @SuppressWarnings("unchecked")
+      State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
+  
+      UpdatableSketch<Double, DoubleSummary> sketch1 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
+      sketch1.update(1, 1.0);
+      sketch1.update(2, 2.0);
+      eval.merge(state, Arrays.asList(
+        new IntWritable(DEFAULT_NOMINAL_ENTRIES),
+        new Text("Min"),
+        new BytesWritable(sketch1.compact().toByteArray()))
+      );
+  
+      UpdatableSketch<Double, DoubleSummary> sketch2 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
+      sketch2.update(1, 2.0);
+      sketch2.update(2, 1.0);
+      eval.merge(state, Arrays.asList(
+        new IntWritable(DEFAULT_NOMINAL_ENTRIES),
+        new Text("Min"),
+        new BytesWritable(sketch2.compact().toByteArray()))
+      );
+  
+      Object result = eval.terminate(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof BytesWritable);
+      Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+      SketchIterator<DoubleSummary> it = resultSketch.iterator();
+      while (it.next()) {
+        Assert.assertEquals(it.getSummary().getValue(), 1.0);
+      }
     }
-
-    eval.close();
   }
 
   // COMPLETE mode (single mode, alternative to MapReduce): iterate + terminate
@@ -295,124 +291,121 @@
   public void completeModeDefaultParams() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { binaryInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new UnionDoubleSummaryWithModeSketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
-    DataToDoubleSummarySketchUDAFTest.checkFinalResultInspector(resultInspector);
-
-    @SuppressWarnings("unchecked")
-    State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
-
-    UpdatableSketch<Double, DoubleSummary> sketch1 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
-    sketch1.update(1, 1.0);
-    sketch1.update(2, 2.0);
-    eval.iterate(state, new Object[] {new BytesWritable(sketch1.compact().toByteArray())});
-
-    UpdatableSketch<Double, DoubleSummary> sketch2 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
-    sketch2.update(1, 2.0);
-    sketch2.update(2, 1.0);
-    eval.iterate(state, new Object[] {new BytesWritable(sketch2.compact().toByteArray())});
-
-    Object result = eval.terminate(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof BytesWritable);
-    Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-    SketchIterator<DoubleSummary> it = resultSketch.iterator();
-    while (it.next()) {
-      Assert.assertEquals(it.getSummary().getValue(), 3.0);
+    try (GenericUDAFEvaluator eval = new UnionDoubleSummaryWithModeSketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
+      DataToDoubleSummarySketchUDAFTest.checkFinalResultInspector(resultInspector);
+  
+      @SuppressWarnings("unchecked")
+      State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
+  
+      UpdatableSketch<Double, DoubleSummary> sketch1 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
+      sketch1.update(1, 1.0);
+      sketch1.update(2, 2.0);
+      eval.iterate(state, new Object[] {new BytesWritable(sketch1.compact().toByteArray())});
+  
+      UpdatableSketch<Double, DoubleSummary> sketch2 = new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).build();
+      sketch2.update(1, 2.0);
+      sketch2.update(2, 1.0);
+      eval.iterate(state, new Object[] {new BytesWritable(sketch2.compact().toByteArray())});
+  
+      Object result = eval.terminate(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof BytesWritable);
+      Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+      SketchIterator<DoubleSummary> it = resultSketch.iterator();
+      while (it.next()) {
+        Assert.assertEquals(it.getSummary().getValue(), 3.0);
+      }
+  
+      eval.reset(state);
+      result = eval.terminate(state);
+      Assert.assertNull(result);
     }
-
-    eval.reset(state);
-    result = eval.terminate(state);
-    Assert.assertNull(result);
-
-    eval.close();
   }
 
   @Test
   public void completeModeExplicitNominalNumEntries() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { binaryInspector, intInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new UnionDoubleSummaryWithModeSketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
-    DataToDoubleSummarySketchUDAFTest.checkFinalResultInspector(resultInspector);
-
-    final int nomNumEntries = 8;
-    @SuppressWarnings("unchecked")
-    State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
-
-    UpdatableSketch<Double, DoubleSummary> sketch1 =
-        new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).setNominalEntries(nomNumEntries).build();
-    sketch1.update(1, 1.0);
-    sketch1.update(2, 2.0);
-    eval.iterate(state, new Object[] {new BytesWritable(sketch1.compact().toByteArray()),
-        new IntWritable(nomNumEntries)});
-
-    UpdatableSketch<Double, DoubleSummary> sketch2 =
-        new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).setNominalEntries(nomNumEntries).build();
-    sketch2.update(1, 2.0);
-    sketch2.update(2, 1.0);
-    eval.iterate(state, new Object[] {new BytesWritable(sketch2.compact().toByteArray()),
-        new IntWritable(nomNumEntries)});
-
-    Object result = eval.terminate(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof BytesWritable);
-    Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-    SketchIterator<DoubleSummary> it = resultSketch.iterator();
-    while (it.next()) {
-      Assert.assertEquals(it.getSummary().getValue(), 3.0);
+    try (GenericUDAFEvaluator eval = new UnionDoubleSummaryWithModeSketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
+      DataToDoubleSummarySketchUDAFTest.checkFinalResultInspector(resultInspector);
+  
+      final int nomNumEntries = 8;
+      @SuppressWarnings("unchecked")
+      State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
+  
+      UpdatableSketch<Double, DoubleSummary> sketch1 =
+          new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).setNominalEntries(nomNumEntries).build();
+      sketch1.update(1, 1.0);
+      sketch1.update(2, 2.0);
+      eval.iterate(state, new Object[] {new BytesWritable(sketch1.compact().toByteArray()),
+          new IntWritable(nomNumEntries)});
+  
+      UpdatableSketch<Double, DoubleSummary> sketch2 =
+          new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).setNominalEntries(nomNumEntries).build();
+      sketch2.update(1, 2.0);
+      sketch2.update(2, 1.0);
+      eval.iterate(state, new Object[] {new BytesWritable(sketch2.compact().toByteArray()),
+          new IntWritable(nomNumEntries)});
+  
+      Object result = eval.terminate(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof BytesWritable);
+      Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+      SketchIterator<DoubleSummary> it = resultSketch.iterator();
+      while (it.next()) {
+        Assert.assertEquals(it.getSummary().getValue(), 3.0);
+      }
+  
+      eval.reset(state);
+      result = eval.terminate(state);
+      Assert.assertNull(result);
     }
-
-    eval.reset(state);
-    result = eval.terminate(state);
-    Assert.assertNull(result);
-
-    eval.close();
   }
 
   @Test
   public void completeModeExplicitNominalNumEntriesAndMode() throws Exception {
     ObjectInspector[] inspectors = new ObjectInspector[] { binaryInspector, intInspector, stringInspector };
     GenericUDAFParameterInfo info = new SimpleGenericUDAFParameterInfo(inspectors, false, false);
-    GenericUDAFEvaluator eval = new UnionDoubleSummaryWithModeSketchUDAF().getEvaluator(info);
-    ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
-    DataToDoubleSummarySketchUDAFTest.checkFinalResultInspector(resultInspector);
-
-    final int nomNumEntries = 8;
-    @SuppressWarnings("unchecked")
-    State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
-
-    UpdatableSketch<Double, DoubleSummary> sketch1 =
-        new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).setNominalEntries(nomNumEntries).build();
-    sketch1.update(1, 1.0);
-    sketch1.update(2, 2.0);
-    eval.iterate(state, new Object[] {new BytesWritable(sketch1.compact().toByteArray()),
-        new IntWritable(nomNumEntries), new Text("Max")});
-
-    UpdatableSketch<Double, DoubleSummary> sketch2 =
-        new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).setNominalEntries(nomNumEntries).build();
-    sketch2.update(1, 2.0);
-    sketch2.update(2, 1.0);
-    eval.iterate(state, new Object[] {new BytesWritable(sketch2.compact().toByteArray()),
-        new IntWritable(nomNumEntries), new Text("Max")});
-
-    Object result = eval.terminate(state);
-    Assert.assertNotNull(result);
-    Assert.assertTrue(result instanceof BytesWritable);
-    Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
-    Assert.assertEquals(resultSketch.getEstimate(), 2.0);
-    SketchIterator<DoubleSummary> it = resultSketch.iterator();
-    while (it.next()) {
-      Assert.assertEquals(it.getSummary().getValue(), 2.0);
+    try (GenericUDAFEvaluator eval = new UnionDoubleSummaryWithModeSketchUDAF().getEvaluator(info)) {
+      ObjectInspector resultInspector = eval.init(Mode.COMPLETE, inspectors);
+      DataToDoubleSummarySketchUDAFTest.checkFinalResultInspector(resultInspector);
+  
+      final int nomNumEntries = 8;
+      @SuppressWarnings("unchecked")
+      State<DoubleSummary> state = (State<DoubleSummary>) eval.getNewAggregationBuffer();
+  
+      UpdatableSketch<Double, DoubleSummary> sketch1 =
+          new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).setNominalEntries(nomNumEntries).build();
+      sketch1.update(1, 1.0);
+      sketch1.update(2, 2.0);
+      eval.iterate(state, new Object[] {new BytesWritable(sketch1.compact().toByteArray()),
+          new IntWritable(nomNumEntries), new Text("Max")});
+  
+      UpdatableSketch<Double, DoubleSummary> sketch2 =
+          new UpdatableSketchBuilder<Double, DoubleSummary>(new DoubleSummaryFactory()).setNominalEntries(nomNumEntries).build();
+      sketch2.update(1, 2.0);
+      sketch2.update(2, 1.0);
+      eval.iterate(state, new Object[] {new BytesWritable(sketch2.compact().toByteArray()),
+          new IntWritable(nomNumEntries), new Text("Max")});
+  
+      Object result = eval.terminate(state);
+      Assert.assertNotNull(result);
+      Assert.assertTrue(result instanceof BytesWritable);
+      Sketch<DoubleSummary> resultSketch = Sketches.heapifySketch(Memory.wrap(((BytesWritable) result).getBytes()));
+      Assert.assertEquals(resultSketch.getEstimate(), 2.0);
+      SketchIterator<DoubleSummary> it = resultSketch.iterator();
+      while (it.next()) {
+        Assert.assertEquals(it.getSummary().getValue(), 2.0);
+      }
+  
+      eval.reset(state);
+      result = eval.terminate(state);
+      Assert.assertNull(result);
     }
-
-    eval.reset(state);
-    result = eval.terminate(state);
-    Assert.assertNull(result);
-
-    eval.close();
   }
 
   static void checkIntermediateResultInspector(ObjectInspector resultInspector) {
