From ff0a3aa676a0a85f214698e5faaf82614271a89d Mon Sep 17 00:00:00 2001 From: Johno Crawford Date: Sat, 7 Oct 2017 20:44:52 +0200 Subject: [PATCH] Fix for #88021 high GC pressure when driver configured with serversideprepared statements. --- src/com/mysql/jdbc/ConnectionImpl.java | 36 +++++++++++-------------- src/com/mysql/jdbc/PerConnectionLRUFactory.java | 4 +-- src/com/mysql/jdbc/util/LRUCache.java | 4 +-- 3 files changed, 20 insertions(+), 24 deletions(-) diff --git a/src/com/mysql/jdbc/ConnectionImpl.java b/src/com/mysql/jdbc/ConnectionImpl.java index 14758ce9..54149da0 100644 --- a/src/com/mysql/jdbc/ConnectionImpl.java +++ b/src/com/mysql/jdbc/ConnectionImpl.java @@ -190,18 +190,17 @@ public void init(Connection conn, Properties properties) throws SQLException { * names soon will, so current catalog is a (hidden) component of the name. */ static class CompoundCacheKey { - String componentOne; + final String componentOne; - String componentTwo; + final String componentTwo; - int hashCode; + final int hashCode; CompoundCacheKey(String partOne, String partTwo) { this.componentOne = partOne; this.componentTwo = partTwo; - // Handle first component (in most cases, currentCatalog being NULL.... - this.hashCode = (((this.componentOne != null) ? this.componentOne : "") + this.componentTwo).hashCode(); + this.hashCode = 31 * (componentOne != null ? componentOne.hashCode() : 0) + (componentTwo != null ? componentTwo.hashCode() : 0); } /* @@ -440,7 +439,7 @@ private static boolean nullSafeCompare(String s1, String s2) { * synchronization and at the same time save memory (each charset converter * takes approx 65K of static data). */ - private Map charsetConverterMap = new HashMap(CharsetMapping.getNumberOfCharsetsConfigured()); + private final Map charsetConverterMap = new HashMap(CharsetMapping.getNumberOfCharsetsConfigured()); /** The point in time when this connection was created */ private long connectionCreationTimeMillis = 0; @@ -554,7 +553,7 @@ private static boolean nullSafeCompare(String s1, String s2) { */ private final CopyOnWriteArrayList openStatements = new CopyOnWriteArrayList(); - private LRUCache parsedCallableStatementCache; + private LRUCache parsedCallableStatementCache; private boolean parserKnowsUnicode = false; @@ -581,7 +580,7 @@ private static boolean nullSafeCompare(String s1, String s2) { private boolean readOnly = false; /** Cache of ResultSet metadata */ - protected LRUCache resultSetMetadataCache; + protected LRUCache resultSetMetadataCache; /** The timezone of the server */ private TimeZone serverTimezoneTZ = null; @@ -614,8 +613,8 @@ private static boolean nullSafeCompare(String s1, String s2) { */ private boolean useServerPreparedStmts = false; - private LRUCache serverSideStatementCheckCache; - private LRUCache serverSideStatementCache; + private LRUCache serverSideStatementCheckCache; + private LRUCache serverSideStatementCache; private Calendar sessionCalendar; private Calendar utcCalendar; @@ -2312,14 +2311,14 @@ private void createPreparedStatementCaches() throws SQLException { } if (getUseServerPreparedStmts()) { - this.serverSideStatementCheckCache = new LRUCache(cacheSize); + this.serverSideStatementCheckCache = new LRUCache(cacheSize); - this.serverSideStatementCache = new LRUCache(cacheSize) { + this.serverSideStatementCache = new LRUCache(cacheSize) { private static final long serialVersionUID = 7692318650375988114L; @Override - protected boolean removeEldestEntry(java.util.Map.Entry eldest) { + protected boolean removeEldestEntry(java.util.Map.Entry eldest) { if (this.maxElements <= 1) { return false; } @@ -3163,7 +3162,7 @@ private void initializeDriverProperties(Properties info) throws SQLException { } if (getCacheCallableStatements()) { - this.parsedCallableStatementCache = new LRUCache(getCallableStatementCacheSize()); + this.parsedCallableStatementCache = new LRUCache(getCallableStatementCacheSize()); } if (getAllowMultiQueries()) { @@ -3171,7 +3170,7 @@ private void initializeDriverProperties(Properties info) throws SQLException { } if (getCacheResultSetMetadata()) { - this.resultSetMetadataCache = new LRUCache(getMetadataCacheSize()); + this.resultSetMetadataCache = new LRUCache(getMetadataCacheSize()); } if (getSocksProxyHost() != null) { @@ -4277,11 +4276,8 @@ public void realClose(boolean calledExplicitly, boolean issueRollback, boolean s } - private String makePreparedStatementCacheKey(String catalog, String query) { - StringBuilder key = new StringBuilder(); - key.append("/*").append(catalog).append("*/"); - key.append(query); - return key.toString(); + private CompoundCacheKey makePreparedStatementCacheKey(String catalog, String query) { + return new CompoundCacheKey(catalog, query); } public void recachePreparedStatement(ServerPreparedStatement pstmt) throws SQLException { diff --git a/src/com/mysql/jdbc/PerConnectionLRUFactory.java b/src/com/mysql/jdbc/PerConnectionLRUFactory.java index 5885e8c9..6863f949 100644 --- a/src/com/mysql/jdbc/PerConnectionLRUFactory.java +++ b/src/com/mysql/jdbc/PerConnectionLRUFactory.java @@ -40,13 +40,13 @@ class PerConnectionLRU implements CacheAdapter { private final int cacheSqlLimit; - private final LRUCache cache; + private final LRUCache cache; private final Connection conn; protected PerConnectionLRU(Connection forConnection, int cacheMaxSize, int maxKeySize) { final int cacheSize = cacheMaxSize; this.cacheSqlLimit = maxKeySize; - this.cache = new LRUCache(cacheSize); + this.cache = new LRUCache(cacheSize); this.conn = forConnection; } diff --git a/src/com/mysql/jdbc/util/LRUCache.java b/src/com/mysql/jdbc/util/LRUCache.java index 3264992e..d72e752a 100644 --- a/src/com/mysql/jdbc/util/LRUCache.java +++ b/src/com/mysql/jdbc/util/LRUCache.java @@ -26,7 +26,7 @@ import java.util.LinkedHashMap; import java.util.Map.Entry; -public class LRUCache extends LinkedHashMap { +public class LRUCache extends LinkedHashMap { private static final long serialVersionUID = 1L; protected int maxElements; @@ -41,7 +41,7 @@ public LRUCache(int maxSize) { * @see java.util.LinkedHashMap#removeEldestEntry(java.util.Map.Entry) */ @Override - protected boolean removeEldestEntry(Entry eldest) { + protected boolean removeEldestEntry(Entry eldest) { return (size() > this.maxElements); } }