提交 c080d3a7 authored 作者: Thomas Mueller's avatar Thomas Mueller

When restarting a web application in Tomcat, an exception is thrown sometimes.

上级 5f720638
...@@ -81,9 +81,10 @@ public class MemoryUtils { ...@@ -81,9 +81,10 @@ public class MemoryUtils {
} }
/** /**
* Check if the classloader or virtual machine is shut down. In this case * Check if Tomcat has set the static references to null,
* static references are set to null, which can cause NullPointerExceptions * which can cause a NullPointerException. A workaround is to
* and can be confusing because it looks like a bug in the application. * disable the system property org.apache.catalina.loader.
* WebappClassLoader.ENABLE_CLEAR_REFERENCES
* *
* @return true if static references are set to null * @return true if static references are set to null
*/ */
......
...@@ -24,40 +24,6 @@ public class StringCache { ...@@ -24,40 +24,6 @@ public class StringCache {
// utility class // utility class
} }
// testing: cacheHit / miss are public!
// public static int cacheHit = 0, cacheMiss = 0;
// 4703
// public static String get(String s) {
// if (s == null) {
// return s;
// } else if (s.length() == 0) {
// return "";
// }
// if (!Constants.USE_OBJECT_CACHE
// || !ENABLED || s.length() > MAX_CACHE_SIZE / 10) {
// return s;
// }
// int hash = s.hashCode();
// int index = hash & (Constants.OBJECT_CACHE_SIZE - 1);
// String cached = cache[index];
// if (cached != null) {
// if (s.equals(cached)) {
// // cacheHit++;
// return cached;
// }
// }
// // cacheMiss++;
// replace(index, s);
// return s;
// }
// 3500
// public static String get(String s) {
// return s;
// }
// 3906
/** /**
* Get the string from the cache if possible. If the string has not been * Get the string from the cache if possible. If the string has not been
* found, it is added to the cache. If there is such a string in the cache, * found, it is added to the cache. If there is such a string in the cache,
...@@ -75,25 +41,18 @@ public class StringCache { ...@@ -75,25 +41,18 @@ public class StringCache {
} else if (s.length() == 0) { } else if (s.length() == 0) {
return ""; return "";
} }
String[] cache = (String[]) softCache.get();
int hash = s.hashCode(); int hash = s.hashCode();
if (cache == null) { String[] cache = getCache();
try { if (cache != null) {
cache = new String[SysProperties.OBJECT_CACHE_SIZE]; int index = hash & (SysProperties.OBJECT_CACHE_SIZE - 1);
} catch (OutOfMemoryError e) { String cached = cache[index];
return s; if (cached != null) {
} if (s.equals(cached)) {
softCache = new SoftReference(cache); return cached;
} }
int index = hash & (SysProperties.OBJECT_CACHE_SIZE - 1);
String cached = cache[index];
if (cached != null) {
if (s.equals(cached)) {
// cacheHit++;
return cached;
} }
cache[index] = s;
} }
cache[index] = s;
return s; return s;
} }
...@@ -115,18 +74,15 @@ public class StringCache { ...@@ -115,18 +74,15 @@ public class StringCache {
} else if (s.length() == 0) { } else if (s.length() == 0) {
return ""; return "";
} }
String[] cache = (String[]) softCache.get();
int hash = s.hashCode(); int hash = s.hashCode();
if (cache == null) { String[] cache = getCache();
cache = new String[SysProperties.OBJECT_CACHE_SIZE];
softCache = new SoftReference(cache);
}
int index = hash & (SysProperties.OBJECT_CACHE_SIZE - 1); int index = hash & (SysProperties.OBJECT_CACHE_SIZE - 1);
String cached = cache[index]; if (cache != null) {
if (cached != null) { String cached = cache[index];
if (s.equals(cached)) { if (cached != null) {
// cacheHit++; if (s.equals(cached)) {
return cached; return cached;
}
} }
} }
// create a new object that is not shared // create a new object that is not shared
...@@ -137,6 +93,26 @@ public class StringCache { ...@@ -137,6 +93,26 @@ public class StringCache {
return s; return s;
} }
private static String[] getCache() {
String[] cache;
// softCache can be null due to a Tomcat problem
// a workaround is disable the system property org.apache.
// catalina.loader.WebappClassLoader.ENABLE_CLEAR_REFERENCES
if (softCache != null) {
cache = (String[]) softCache.get();
if (cache != null) {
return cache;
}
}
try {
cache = new String[SysProperties.OBJECT_CACHE_SIZE];
} catch (OutOfMemoryError e) {
return null;
}
softCache = new SoftReference(cache);
return cache;
}
/** /**
* Clear the cache. This method is used for testing. * Clear the cache. This method is used for testing.
*/ */
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论