1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package benchmarks; 18 19import java.lang.ref.PhantomReference; 20import java.lang.ref.ReferenceQueue; 21import java.util.ArrayList; 22import java.util.List; 23import java.util.concurrent.atomic.AtomicInteger; 24 25/** 26 * Benchmark to evaluate the performance of References. 27 */ 28public class ReferenceBenchmark { 29 30 private Object object; 31 32 // How fast can references can be allocated? 33 public void timeAlloc(int reps) { 34 ReferenceQueue<Object> queue = new ReferenceQueue<Object>(); 35 for (int i = 0; i < reps; i++) { 36 new PhantomReference(object, queue); 37 } 38 } 39 40 // How fast can references can be allocated and manually enqueued? 41 public void timeAllocAndEnqueue(int reps) { 42 ReferenceQueue<Object> queue = new ReferenceQueue<Object>(); 43 for (int i = 0; i < reps; i++) { 44 (new PhantomReference<Object>(object, queue)).enqueue(); 45 } 46 } 47 48 // How fast can references can be allocated, enqueued, and polled? 49 public void timeAllocEnqueueAndPoll(int reps) { 50 ReferenceQueue<Object> queue = new ReferenceQueue<Object>(); 51 for (int i = 0; i < reps; i++) { 52 (new PhantomReference<Object>(object, queue)).enqueue(); 53 } 54 for (int i = 0; i < reps; i++) { 55 queue.poll(); 56 } 57 } 58 59 // How fast can references can be allocated, enqueued, and removed? 60 public void timeAllocEnqueueAndRemove(int reps) { 61 ReferenceQueue<Object> queue = new ReferenceQueue<Object>(); 62 for (int i = 0; i < reps; i++) { 63 (new PhantomReference<Object>(object, queue)).enqueue(); 64 } 65 for (int i = 0; i < reps; i++) { 66 try { 67 queue.remove(); 68 } catch (InterruptedException ie) { 69 i--; 70 } 71 } 72 } 73 74 // How fast can references can be implicitly allocated, enqueued, and 75 // removed? 76 public void timeAllocImplicitEnqueueAndRemove(int reps) { 77 ReferenceQueue<Object> queue = new ReferenceQueue<Object>(); 78 List<Object> refs = new ArrayList<Object>(); 79 for (int i = 0; i < reps; i++) { 80 refs.add(new PhantomReference<Object>(new Object(), queue)); 81 } 82 Runtime.getRuntime().gc(); 83 for (int i = 0; i < reps; i++) { 84 try { 85 queue.remove(); 86 } catch (InterruptedException ie) { 87 i--; 88 } 89 } 90 } 91 92 static private class FinalizableObject { 93 AtomicInteger count; 94 95 public FinalizableObject(AtomicInteger count) { 96 this.count = count; 97 } 98 99 @Override 100 protected void finalize() { 101 count.incrementAndGet(); 102 } 103 } 104 105 // How fast does finalization run? 106 public void timeFinalization(int reps) { 107 // Allocate a bunch of finalizable objects. 108 int n = reps; 109 AtomicInteger count = new AtomicInteger(0); 110 for (int i = 0; i < n; i++) { 111 new FinalizableObject(count); 112 } 113 114 // Run GC so the objects will be collected for finalization. 115 Runtime.getRuntime().gc(); 116 117 // Wait for finalization. 118 Runtime.getRuntime().runFinalization(); 119 120 // Double check all the objects were finalized. 121 int got = count.get(); 122 if (n != got) { 123 throw new IllegalStateException( 124 String.format("Only %i of %i objects finalized?", got, n)); 125 } 126 } 127} 128