// Might throw. private SQLiteConnection tryAcquireNonPrimaryConnectionLocked(String sql, int connectionFlags) { // Try to acquire the next connection in the queue. SQLiteConnection connection; final int availableCount = mAvailableNonPrimaryConnections.size(); if (availableCount > 1 && sql != null) { // If we have a choice, then prefer a connection that has the // prepared statement in its cache. for (int i = 0; i < availableCount; i++) { connection = mAvailableNonPrimaryConnections.get(i); if (connection.isPreparedStatementInCache(sql)) { mAvailableNonPrimaryConnections.remove(i); finishAcquireConnectionLocked(connection, connectionFlags); // might throw return connection; } } } if (availableCount > 0) { // Otherwise, just grab the next one. connection = mAvailableNonPrimaryConnections.remove(availableCount - 1); finishAcquireConnectionLocked(connection, connectionFlags); // might throw return connection; } // Expand the pool if needed. int openConnections = mAcquiredConnections.size(); if (mAvailablePrimaryConnection != null) { openConnections += 1; } if (openConnections >= mMaxConnectionPoolSize) { return null; } connection = openConnectionLocked(mConfiguration, false /*primaryConnection*/); // might throw finishAcquireConnectionLocked(connection, connectionFlags); // might throw return connection; }
@SuppressWarnings("unchecked") public static <T> MethodCapturer<T> capture(T obj) { synchronized (s_cache) { MethodCapturer<T> capturer = (MethodCapturer<T>) s_cache.get(obj); if (capturer != null) { return capturer; } final MethodCapturer<T> capturerNew = new MethodCapturer<T>(); Enhancer en = new Enhancer(); en.setSuperclass(obj.getClass()); en.setCallbacks( new Callback[] { new MethodInterceptor() { @Override public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable { capturerNew.setMethod(arg1); return null; } }, new MethodInterceptor() { @Override public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable { return null; } } }); en.setCallbackFilter( new CallbackFilter() { @Override public int accept(Method method) { if (method.getParameterTypes().length == 0 && method.getName().equals("finalize")) { return 1; } return 0; } }); capturerNew.setInstance((T) en.create()); // We expect MethodCapturer is only used for singleton objects here, so we only maintain a // limited cache // here if (s_cache.size() < CACHE_SIZE) { s_cache.put(obj, capturerNew); } return capturerNew; } }
public static void main(String[] args) { WeakHashMap<String, String> map = new WeakHashMap<String, String>(); // 测试数据 // 常量池对象不会回收 map.put("abc", "a"); map.put("d", "tets"); // gc运行已被回收 map.put(new String(""), "d"); // 通知回收 System.gc(); System.runFinalization(); System.out.println(map.size()); }
// Can't throw. private void markAcquiredConnectionsLocked(AcquiredConnectionStatus status) { if (!mAcquiredConnections.isEmpty()) { ArrayList<SQLiteConnection> keysToUpdate = new ArrayList<SQLiteConnection>(mAcquiredConnections.size()); for (Map.Entry<SQLiteConnection, AcquiredConnectionStatus> entry : mAcquiredConnections.entrySet()) { AcquiredConnectionStatus oldStatus = entry.getValue(); if (status != oldStatus && oldStatus != AcquiredConnectionStatus.DISCARD) { keysToUpdate.add(entry.getKey()); } } final int updateCount = keysToUpdate.size(); for (int i = 0; i < updateCount; i++) { mAcquiredConnections.put(keysToUpdate.get(i), status); } } }
private void dispose(boolean finalized) { if (mCloseGuard != null) { if (finalized) { mCloseGuard.warnIfOpen(); } mCloseGuard.close(); } if (!finalized) { // Close all connections. We don't need (or want) to do this // when finalized because we don't know what state the connections // themselves will be in. The finalizer is really just here for CloseGuard. // The connections will take care of themselves when their own finalizers run. synchronized (mLock) { throwIfClosedLocked(); mIsOpen = false; closeAvailableConnectionsAndLogExceptionsLocked(); final int pendingCount = mAcquiredConnections.size(); if (pendingCount != 0) { Log.i( TAG, "The connection pool for " + mConfiguration.label + " has been closed but there are still " + pendingCount + " connections in use. They will be closed " + "as they are released back to the pool."); } wakeConnectionWaitersLocked(); } } }
@NotNull public Object[] getToExpand() { return myToExpand.keySet().toArray(new Object[myToExpand.size()]); }
@NotNull public Object[] getToSelect() { return myToSelect.keySet().toArray(new Object[myToSelect.size()]); }