在具有多个ClassLoader的环境中使用ServiceLoader的最佳实践是什么?文档建议在初始化时创建并保存单个服务实例:
private static ServiceLoader<CodecSet> codecSetLoader = ServiceLoader.load(CodecSet.class);
Run Code Online (Sandbox Code Playgroud)
这将使用当前上下文类加载器初始化ServiceLoader.现在假设此片段包含在使用Web容器中的共享类加载器加载的类中,并且多个Web应用程序想要定义自己的服务实现.这些不会在上面的代码中被提取,甚至可能使用第一个webapps上下文类加载器初始化加载器并向其他用户提供错误的实现.
始终创建新的ServiceLoader似乎是浪费性能,因为它必须每次枚举和解析服务文件.编辑:这甚至可能是一个很大的性能问题,如关于java的XPath实现的答案所示.
其他库如何处理这个?他们是否为每个类加载器缓存实现,他们是否每次都重新分析它们的配置,还是只是忽略了这个问题而只适用于一个类加载器?
我正在尝试使用javax.xml.xpath包在具有多个名称空间的文档上运行XPath表达式,并且我遇到了愚蠢的性能问题.
我的测试文档来自一个真实的生产示例.它大约是600k的xml.该文档是一个相当复杂的Atom提要.
我意识到我正在使用XPath做的事情可以在没有的情况下完成.然而,在其他非常低劣的平台上实现相同的实现表现得非常好.现在,重建我的系统不使用XPath超出了我所能做的范围.
我的测试代码是这样的:
void testXPathPerformance()
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(loadTestDocument());
XPathFactory xpf = XPathFactory.newInstance();
XPath xp = xpf.newXPath();
NamespaceContext names = loadTestNamespaces();
//there are 12 namespaces in names. In this example code, I'm using
//'samplens' instead of the actual namespaces that my application uses
//for simplicity. In my real code, the queries are different text, but
//precisely the same complexity.
xp.setNamespaceContext(names);
NodeList nodes = (NodeList) xp.evaluate("/atom:feed/atom:entry",
doc.getDocumentElement(), XPathConstants.NODESET);
for(int i=0;i<nodes.getLength();i++) …Run Code Online (Sandbox Code Playgroud) 我的情况一直困扰着我好几个月:我不断获得OOM异常(堆空间)和检查堆转储我发现了数百万个我从未分配但可能在底层库中分配的对象实例.经过大量的血,汗和泪,我设法本地化了产生内存泄漏的代码,我编写了一个最小的,完整的,可验证的代码示例来说明这一点:
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.scene.web.WebEngine;
import javafx.stage.Stage;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class MVC extends Application implements ChangeListener<Worker.State>{
private final WebEngine engine = new WebEngine();
private final String url = "https://biblio.ugent.be/publication?sort=publicationstatus.desc&sort=year.desc&limit=250&start=197000";
private final XPath x = XPathFactory.newInstance().newXPath();
@Override
public void start(Stage primaryStage) throws Exception {
System.setProperty("jsse.enableSNIExtension", "false");
engine.getLoadWorker().stateProperty().addListener(this);
engine.load(url);
}
public static void main(String[] args) {
launch(args);
}
private NodeList eval(Node context, …Run Code Online (Sandbox Code Playgroud) 使用myBatis standAlone(Atlassian jira插件(OSGi)环境)
发生以下错误.
[INFO] [talledLocalContainer] org.apache.ibatis.exceptions.PersistenceException:
[INFO] [talledLocalContainer] ### Error building SqlSession.
[INFO] [talledLocalContainer] ### Cause: java.lang.RuntimeException: XPathFactory#newInstance() failed to create an XPathFactory for the default o
bject model: http://java.sun.com/jaxp/xpath/dom with the XPathFactoryConfigurationException: javax.xml.xpath.XPathFactoryConfigurationException: java.
util.ServiceConfigurationError: javax.xml.xpath.XPathFactory: Provider org.apache.xpath.jaxp.XPathFactoryImpl not found
[INFO] [talledLocalContainer] ### Cause: java.lang.RuntimeException: XPathFactory#newInstance() failed to create an XPathFactory for the default object model: http://java.sun.com/jaxp/xpath/dom with the XPathFactoryConfigurationException:javax.xml.xpath.XPathFactoryConfigurationException: java.util.ServiceConfigurationError: javax.xml.xpath.XPathFactory: Provider org.apache.xpath.jaxp.XPathFactoryImpl not found
Run Code Online (Sandbox Code Playgroud)
源代码
static {
try {
// set SessionFactory
if (MyBatisConnectionFactory.sqlSessionFactory == null) …Run Code Online (Sandbox Code Playgroud) 我的代码太慢,但我不知道如何改进它。从磁盘读取 1k 文件到 DOM 大约需要 20 毫秒,这可能还不错,具体取决于磁盘,但是我还有另外 20 毫秒来处理 xpath 语句,这太多了。这是一些带有时间注释的示例代码。我该如何改进代码?
这发生在构建时:
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = this.dbFactory.newDocumentBuilder();
XPathExpression[] ex = new XPathExpression[]{about 30 different expressions}
XPathExpression mainEx =xPath.compile("/rootElement/firstLevel/secondLevel");
Run Code Online (Sandbox Code Playgroud)
然后是代码:
Document doc = this.dBuilder.parse("somefile.xml");
//took 20 ms until here
NodeList nodes = (NodeList) mainEx .evaluate,doc, XPathConstants.NODESET);
//took another 20 ms until here !!!
for (int i = 0; i < nodes.getLength(); i++) {
Node n = nodes.item(i);
for (XPathExpression e:ex) {
String v = (String) e.evaluate(n, XPathConstants.STRING);
if …Run Code Online (Sandbox Code Playgroud) java ×5
xpath ×3
android ×1
classloader ×1
dom ×1
javafx ×1
jaxp ×1
jira-plugin ×1
memory-leaks ×1
mybatis ×1
osgi ×1
performance ×1
xml ×1