我有一个BytecodeCacheService类,它被设计为singlton。在启动期间,NPE例外被抛弃。
代码如下所示:
wsadmin.sh -lang jython -c "print AdminControl.queryNames ('name=WebContainer,process=server1,platform=dynamicproxy,node=node1,version=8.5.5.8,type=ThreadPool').splitlines()"
我在这里试了一下:
1)运行BytecodeService的main方法,运行成功。结果是:
public class BytecodeCacheService {
public final static class CachePlacer{
public final static BytecodeCacheService _instance = new BytecodeCacheService();
}
private static ICache _cacheInstance = null ;
static{
_cacheInstance = new GlobalCache();
System.out.println("Init "+_cacheInstance);
}
private BytecodeCacheService(){
_logger.debug("Start Bytecode Cache Service");
}
public static BytecodeCacheService get(){
return CachePlacer._instance;
}
public static void main(String[] args){
ICache cache = new GlobalCache();
System.out.println(cache.toString());
}
}
class GlobalCache implements ICache{
private ConcurrentMap<IGraphNode, BytecodeResource> _map = new ConcurrentHashMap<IGraphNode, BytecodeResource>();
//Customize below values via annotation (xml configurtion or others)
private final int MAX_ENTITES = Config.CACHE_GLOBAL_CACHE_SIZE; // The maximal entities allowed in the GlobalCache (This is in theory).
private final float _ratio = Config.CACHE_GLOBAL_CACHE_RATIO; // Each purge removes (1-_ratios)*entities.
ScheduledExecutorService exec = Executors.newScheduledThreadPool(1, new ThreadFactory(){
final AtomicInteger count = new AtomicInteger(1);
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread();
thread.setName("GLobalCache: purge "+count.getAndIncrement());
thread.setDaemon(true);
return thread;
}
});
public GlobalCache(){
System.out.println("init 1...");
line 171: exec.scheduleAtFixedRate(()->{
//@TODO the future developer can think up better purge policy. Here I only use a simple NON-STRICT Longest un-used first.
// if(_map.size() > MAX_ENTITES*_ratio){
// int len = (int) (MAX_ENTITES*(1-_ratio));
// while(len>0){
// IGraphNode longest = null;
// long max=-1;
// Iterator<IGraphNode> iter = _map.keySet().iterator();
// //It is NON-Strict because during iteration the BytecodeClass in global Cache might be updated.
// while(iter.hasNext()){
// IGraphNode node = iter.next();
// BytecodeResource resource = _map.get(node);
// if(longest == null || max < resource.getLife()){
// longest = node;
// max = _map.get(longest).getLife();
// }
// }
// if(longest!=null)
// _map.remove(longest);
// }
// len--;
// }
System.out.println("Smile...");
}, 1, 2, TimeUnit.SECONDS);
System.out.println("init 2...");
}
}
2),运行BytecodeCacheService.get(),报告:
init 1...
init 2...
Init code.jit.asm.services.GlobalCache@5518e919
init 1...
init 2...
code.jit.asm.services.GlobalCache@11ebb918
第171行是班级init 1...
29/Mar/2016:16:19:03:347 -0300 [main] DEBUG c.j.a.services.BytecodeCacheService - Start Bytecode Cache Service
java.lang.invoke.ConstantObjectHandle
J9VMInternals.java:137:in `ensureError': java.lang.ExceptionInInitializerError
from J9VMInternals.java:126:in `recordInitializationFailure'
from BytecodeGenerator.java:59:in `action'
from BytecodeGenerator.java:333:in `run'
from BytecodeGenerator.java:328:in `generate'
from CallSite.java:137:in `jitMethodHandle'
from MutableCallSite.java:61:in `<init>'
from SwitchPoint.java:135:in `<init>'
from FailoverSwitchPointInvalidator.java:34:in `<clinit>'
from OptoFactory.java:72:in `newGlobalInvalidator'
from Ruby.java:5047:in `<init>'
from Ruby.java:329:in `newInstance'
from Main.java:272:in `internalRun'
from Main.java:231:in `run'
from Main.java:200:in `main'
Caused by:
BytecodeCacheService.java:171:in `<init>': java.lang.NullPointerException
from BytecodeCacheService.java:40:in `<clinit>'
from BytecodeGenerator.java:59:in `action'
from BytecodeGenerator.java:333:in `run'
from BytecodeGenerator.java:328:in `generate'
from CallSite.java:137:in `jitMethodHandle'
from MutableCallSite.java:61:in `<init>'
from SwitchPoint.java:135:in `<init>'
from FailoverSwitchPointInvalidator.java:34:in `<clinit>'
from OptoFactory.java:72:in `newGlobalInvalidator'
from Ruby.java:5047:in `<init>'
from Ruby.java:329:in `newInstance'
from Main.java:272:in `internalRun'
from Main.java:231:in `run'
from Main.java:200:in `main'
中的exec.scheduleAtFixedRate({}->{}..)
。我调试它,并在此方法调用中抛出异常。
我使用lambda函数的方式是否有任何错误(我目前对这部分不熟悉)?谁能解释1)和2)之间的不同结果?我在这里使用Java 8和J9 JVM。