gpt4 book ai didi

java - 内存不足错误: unable to create new native thread while using Executor

转载 作者:行者123 更新时间:2023-12-02 03:50:22 26 4
gpt4 key购买 nike

我有一个执行器服务,其池大小为 1。

代码:

@POST
@Path("insertOrUpdate")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response insertOrUpdate(final String user) {



try {
new MYSQLProvider().insertOrUpdate(user);
resulTObj.put("success", true);
resulTObj.put("msg", "");

ExecutorService executor = Executors.newFixedThreadPool(1);
executor.execute( new Runnable() {

@Override
public void run() {
//fetch list of all the user ids here and fire a multicast

log4j.info("Executor called");

Map<String, String> m = new HashMap<String, String>();
m.put("TAG", "MOVEMENT");
m.put("user", user);
GCMServerJava.sendMsgToAll(m);


}
});

} catch (SQLException | JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
resulTObj.put("success", false);
resulTObj.put("msg", e.getMessage());
}




return Response.status(200).entity(resulTObj.toString()).build();

}

在服务器上运行几天后,我收到 OutOfMemory 错误。为什么会发生这种情况?到处都提到 Java 堆大小较小,我们需要增加它。我的理解是,由于我的线程池大小只有 1,因此只有一个后台线程在运行,其余线程都在队列中等待。在这种情况下,内存分配应该足够。我是否遗漏了什么,以及如何解决这个问题。

谢谢

最佳答案

只是为了为 future 的读者提供答案:

该解决方案的主要思想是仅初始化 ExecutorService 实例一次,并在每个请求上重用它(请参阅上面的注释)。

如果您使用单例资源或以某种方式手动实例化它们,最好将执行器服务保留为实例字段并仅在操作方法中引用它:

public class MySqlResource{

private final ExecutorService executor;

public MySqlResource() {
this.executor = Executors.newFixedThreadPool(1);
}

@POST
@Path("insertOrUpdate")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response insertOrUpdate(final String user) {

try {
new MYSQLProvider().insertOrUpdate(user);
resulTObj.put("success", true);
resulTObj.put("msg", "");

executor.execute( new Runnable() {

@Override
public void run() {
//...run() code goes here
}
});
} catch (SQLException | JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
resulTObj.put("success", false);
resulTObj.put("msg", e.getMessage());
}

return Response.status(200).entity(resulTObj.toString()).build();
}
}

注意:如上所述,只有将上述资源作为单例提交(使用应用程序类的 getSingletons() 方法)时,这才有效。如果不是,则更改无效,因为容器将在每次请求时实例化资源的实例。

或者,您可以使用单例实例创建一个单独的类,然后调用它。但最合理的解决方法是将实例字段设为静态并将其设置在静态初始化 block 中:

public class MySqlResource {

//Note that the field is now static
private static final ExecutorService executor;

static {
MySqlResource.executor = Executors.newFixedThreadPool(1);
}

//.....
//Then the method can invoke it just as in the previous solution:
public Response insertOrUpdate(final String user) {
//...
MySqlResource.executor.execute( new Runnable() {

@Override
public void run() {
//...run() code goes here
}
});
//...
}
}

如果您对静态字段有疑问,那么您可以创建一个单独的单例类实例来保存执行程序服务对象。

有关单例资源的信息,请在此处查看 Application 类的 JavaDocs:http://docs.oracle.com/javaee/7/api/javax/ws/rs/core/Application.html#getSingletons--

关于java - 内存不足错误: unable to create new native thread while using Executor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35936217/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com