我与物理设备有一个长期运行的 CXF SOAP 连接。随着时间的推移,我看到 org.apache.cxf.ws.addressing.soap.MAPCodec 对象保留堆。看来 ConcurrentHashpMap uncorlatedExchanges 正在增长,并且映射中的条目没有被清除。仅运行 12 小时后,该地图现已包含近 54,000 个条目。有什么方法可以清除不相关的交换吗?我正在使用CXF 3.4.0。
谢谢大卫
同样,解决方法是在 uncorlatedExchanges 中使用弱密钥...使用 https://guava.dev/
public static <T> boolean setPrivateFinalField(Class<T> clazz, String fieldName, T instance, Object value) {
try {
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(instance, value);
return true;
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return false;
}
....
WSAddressingFeature wsAddressingFeature = new WSAddressingFeature();
wsAddressingFeature.initialize(client, client.getBus());
client.getInInterceptors().stream().filter(MAPCodec.class::isInstance).findAny().map(MAPCodec.class::cast).ifPresent(mapCodec -> {
// OOM workaround on no-relates-to responses
Map<Object, Object> weakMap = new MapMaker().weakKeys().makeMap();
setPrivateFinalField(MAPCodec.class, "uncorrelatedExchanges", mapCodec, weakMap);
});