0

我有一个多线程爬虫。在这个程序中,如果我加载了很多种子,我会得到一个错误。我看到了java.lang.OutOfMemoryError,想也许内存不够。我尝试crawler.jar使用这些参数运行文件:java -Xms512m -Xmx3G -jar crawler.jar但到目前为止,还没有运气。

这是程序的 StackTrace:

Exception in thread "main" java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: java.lang.OutOfMemoryError: unable to create new native thread
        at java.lang.Thread.start0(Native Method)
        at java.lang.Thread.start(Thread.java:597)
        at com.sleepycat.je.utilint.DaemonThread.runOrPause(DaemonThread.java:99)
        at com.sleepycat.je.dbi.EnvironmentImpl.runOrPauseDaemons(EnvironmentImpl.java:772)
        at com.sleepycat.je.dbi.EnvironmentImpl.envConfigUpdate(EnvironmentImpl.java:717)
        at com.sleepycat.je.dbi.EnvironmentImpl.finishInit(EnvironmentImpl.java:579)
        at com.sleepycat.je.dbi.DbEnvPool.getEnvironment(DbEnvPool.java:204)
        at com.sleepycat.je.Environment.makeEnvironmentImpl(Environment.java:230)
        at com.sleepycat.je.Environment.<init>(Environment.java:212)
        at com.sleepycat.je.Environment.<init>(Environment.java:166)
        ...

这与我怀疑的记忆有关吗?-Xms512m -Xmx3G当我使用运行 jar 文件时添加工作java -jar吗?

我运行了任务管理器(我在 Windows Server 上运行),但运行应用程序后,内存并没有那么高!我错了吗?

4

3 回答 3

4

-Xms512m -Xmx3G选项只会影响 JVM的堆大小,不会解决您的问题。

但是,在大多数情况下,默认线程数限制应该足够了。您可以通过调整 JVM/系统选项来增加限制,但无论您创建多少线程,系统的容量都受限于您的计算机资源。例如cpu、内存、网络等。

我建议从不同的角度解决这个问题:

  • 尝试在工作线程之间共享 Environment 实例。
  • 尝试将并发级别控制在系统繁忙且不触及线程数限制的速率。
于 2013-01-30T05:45:39.757 回答
2

这类错误通常可以通过一些简单的分析来解决。JDK 随 jvisualvm 一起提供。

例如 C:\Program Files\Java\jdk1.7.0_11\bin\jvisualvm.exe

您将能够看到堆大小的图表,并且还值得检查 PermGen 空间。

如果这没有显示任何内容,请尝试在运行 jar 时添加 -XX:-HeapDumpOnOutOfMemoryError,然后将堆转储加载到 Eclipse 内存分析器中。

于 2013-01-30T05:07:42.867 回答
1

您产生的线程数超过了 Java 所能承受的。尝试使用此 JVM 参数缩小堆栈大小:-Xss128k

如果不是这样,也许你正在达到操作系统限制。如果您使用的是 Linux,请将这样的一行添加到~/.profileulimit -u 4096

发生这种情况的原因有很多,具体取决于您的代码和您使用的操作系统。

于 2013-01-30T05:13:16.250 回答