- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我们正在编写一个应用程序,它使用ThreadPoolExecutor
的自定义扩展来处理一堆Runnable
。在开发应用程序时,我们遇到了 Runnable
类中发生的 OutOfMemoryError
错误。但是,ThreadPoolExecutor
并没有像我们期望的那样调用 afterExecute()
,而是继续运行。
我已将代码缩减为一个小型的、可重复的应用程序。
ThreadPoolTest.java:
package org.codechimp.threadpool;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadPoolTest {
/**
* @param args
*/
public static void main(String[] args) {
LinkedBlockingQueue<Runnable> threadQueue = new LinkedBlockingQueue<Runnable>();
ThreadPoolExecutor executor = new MyThreadPoolExecutor(10, Integer.MAX_VALUE, 2000, TimeUnit.MILLISECONDS, threadQueue);
// Create a bunch of Runnables now...
for (int i = 0; i < 10000; i++) {
executor.execute(new MyRunnable(i));
if (i % 100 == 0) {
System.out.println("Queued " + i + " Runnables");
}
if (i % 1000 == 0) {
try {
Thread.sleep(1);
} catch (InterruptedException ignored) { }
}
}
System.out.println("Done queing the Runnables.");
while (!executor.isTerminated() && !executor.isTerminating() && executor.getQueue().size() > 0) {
System.out.println(executor.getQueue().size() + " Runnables in the queue.");
try {
Thread.sleep(1000);
} catch (InterruptedException ignored) { }
}
System.out.println("Runnable queue has stopped processing.");
executor.shutdown();
try {
executor.awaitTermination(10, TimeUnit.MINUTES);
} catch (InterruptedException ignored) { }
System.out.println("Shutdown completed...exiting");
}
}
MyThreadPoolExecutor.java:
package org.codechimp.threadpool;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class MyThreadPoolExecutor extends ThreadPoolExecutor {
public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
}
public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, handler);
}
public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory);
}
public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
if (t != null) {
System.out.println("We got an error: " + t);
int remaining = this.shutdownNow().size();
System.out.println(remaining + " Runnables left in the queue");
}
}
}
MyRunnable.java
package org.codechimp.threadpool;
import org.apache.commons.lang.math.RandomUtils;
public class MyRunnable implements Runnable {
private int runnableNumber;
private int counter = 0;
public MyRunnable(int number) {
this.runnableNumber = number;
}
/**
* Simple runnable that generates an OutOfMemoryError after the 1000th loop
*/
public void run() {
while (counter < 1000) {
counter++;
if (counter % 100 == 0) {
System.out.println("\tRunnable " + this.runnableNumber + " reached " + this.counter + ".");
}
if (this.runnableNumber == 15 && this.counter % 200 == 0) {
throw new OutOfMemoryError("This is a test!");
}
int wait = RandomUtils.nextInt(100);
if (wait > 0) {
try {
//System.out.println("\tRunnable " + this.runnableNumber + " waiting " + wait + ".");
Thread.sleep(wait);
} catch (InterruptedException e) {
throw new RuntimeException("Thread.sleep() failed", e);
}
}
}
}
}
这是一个 super 简单的示例,它将在 MyThreadPoolExectuor
中创建 10k 个 MyRunnable
,并随着计数器的增加打印出一些状态消息。第 16 个可运行对象(编号 15,从 0 开始计数)将在第 200 个增量时抛出 OutOfMemoryError
。如果 MyThreadPoolExecutor
的 afterExecute()
获得 Throwable
,它将打印一条消息。当我在 Java 6 和 Java 7 下运行它时,它永远不会打印此消息。
我们如何使应用程序在所有 Throwable
上保释?我们真的想在那时终止事情。
更新/编辑:
我正在更新此内容,因为我的要求似乎有些困惑。 我知道错误被打印出来。问题不在于 ThreadPoolExecutor 没有打印 OutOfMemoryError
,问题在于,如标题和我提出的问题中所述最后,afterExecute()
不会因 Error
被调用。由于 OutOfMemoryError
是 Error
的子类,这意味着当发生错误时我无法停止代码。
再次,请阅读代码试图执行的操作。它肯定是在尝试“处理”该错误。事实上,它试图通过调用 shutdownNow()
来停止 ThreadPoolExecutor。但是,由于正在生成的 Error
被以某种方式抑制,因此该代码不会被执行。结果,应用程序只是继续运行,忽略了它到处喷出 OOME 的事实。
再问一个问题:
How do I detect a Runnable has recieved an Error (OutOfMemoryError or other) and terminate the ThreadPoolExecutor so the app will simply stop in it's tracks?
最佳答案
我通过代码简单说明一下,如果查看runWorker()实现,发现错误仍然是在afterExecute()中发送的。因此,如果使用 afterExecute 钩子(Hook),则无法跳过错误。请引用https://stackoverflow.com/a/50480190/5620851 .
final void runWorker(Worker arg0) {
Thread arg1 = Thread.currentThread();
Runnable arg2 = arg0.firstTask;
arg0.firstTask = null;
arg0.unlock();
boolean arg3 = true;
try {
while (arg2 != null || (arg2 = this.getTask()) != null) {
arg0.lock();
..
try {
this.beforeExecute(arg1, arg2);
Object arg4 = null;
try {
arg2.run();
} catch (RuntimeException arg27) {
arg4 = arg27;
throw arg27;
} catch (Error arg28) {
arg4 = arg28;
throw arg28;
} catch (Throwable arg29) {
arg4 = arg29;
throw new Error(arg29);
} finally {
this.afterExecute(arg2, (Throwable) arg4);
}
} finally {
arg2 = null;
++arg0.completedTasks;
arg0.unlock();
}
}
arg3 = false;
} finally {
this.processWorkerExit(arg0, arg3);
}
}
关于java - ThreadPoolExecutor 忽略错误 (OutOfMemoryError),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25687963/
我正在尝试将用户提供的经纬度值与数据库中的经纬度值进行比较。如果它们在彼此半径 15 公里内,则应更改 TextView 。但我面临以下错误, 我的数据库包含值 source lat = 19.218
我在我的应用程序中使用改造来下载一些媒体文件,如视频、mp3、jpg、pdf 等。当我想下载一个 55MB 的 mp4 格式的大文件时,这是一个问题。当我想下载这个文件时,我收到这样的错误: OutO
所以我正在创建一个 Android 应用程序,这段代码引发了 "Caused by: java.lang.OutOfMemoryError: OutOfMemoryError thrown while
直到昨天,我的应用程序运行良好,但我所做的是,由于某些原因,我不得不在 Android Studio 中打开具有不同工作空间的同一个应用程序。从那时起,当我尝试运行该应用程序时,我遇到了以下异常,所以
我正在尝试构建一个应用程序,其中客户端将其屏幕发送到服务器,客户端仅在上次发送屏幕和最新捕获的屏幕之间存在差异时才发送其屏幕(以便该程序在网络)。服务器使用 JFrame 和 JLabel 来显示图像
我正在尝试使用内存映射模式在 cupy 中加载一些较大的 .npy 文件,但我不断遇到 OutOfMemoryError 。 我认为,由于它是在内存映射模式下打开的,因此此操作不应该占用太多内存,因为
我正在尝试对基于 ant 的(Netbeans RCP)项目进行分级并找到奇怪的分级行为。 我用探查器做了一些观察,得到了下一个结果。 环境配置 Gradle 1.9 Build time: 20
我有一个应用程序可以进行网络调用并检索 XML 数据。如果没有太多数据,下面的代码可以正常工作。 public class WebClient { private static final S
在我的应用程序中,我每 3 分钟刷新一次数据。如果应用程序可以工作几个小时,我会遇到这样的错误: java.lang.OutOfMemoryError at org.apache.http.util.
我在我的一个应用程序中偶尔收到 OutOfMemoryError: (Heap Size=49187KB, Allocated=41957KB)。我该怎么做才能诊断? 01-09 10:32:02
对于学校项目,我必须编写不同类型的算法。问题是,我得到了一个工作算法。但是我必须多次运行它,一段时间后它给了我以下错误: Exception in thread "main" java.lang.Ou
这个问题在这里已经有了答案: 8年前关闭。 Possible Duplicate: Recursive function causing a stack overflow 完成示例惰性序列 here
我收到 java.lang.OutOfMemoryError 错误,即使我还有足够的空闲 RAM。我进行的内存转储在 200MB 到 1GB 之间,而我的服务器有 24GB 的 RAM。我设置了 -X
我不明白为什么这段代码没有OutOfMemoryError public static void main(String[] args) { Object[] ref = new Object
我正在使用这个语句 //some code int a[][]=new int[5000000][5000000]; //some code 并使用命令运行它 java -mx512m Test 它给
今天我在玩OOM错误,我发现了一些我自己无法解释的东西。 我尝试分配一个比堆大的数组,期望 “请求的阵列大小超出 VM 限制”错误,但我得到一个“ Java 堆空间 ”错误。 根据JDK 11 doc
我有一个显示图像的简单页面。来源是 URL var img = new Image (); var source = new UriImageSource { Uri =
我有一个 Java Spring Boot 应用程序。它是一个非常大的应用程序,具有许多服务,并且可以执行大量任务。我尝试实现的新任务之一是从 Oracle DB 读取一些数据并通过 REST 将其发
我正在尝试使用流读取一个非常大的文件,因此我需要并行流而不是每行迭代...我正在尝试如下: String cont = new String(Files.readAllBytes(Paths.get(
假设我们的最大内存为 256M,为什么这段代码可以工作: public static void main(String... args) { for (int i = 0; i < 2; i++)
我是一名优秀的程序员,十分优秀!