Java 创建太多线程

问题描述 投票:0回答:0

我正在为学校做一个模拟网络(特别是传输层、网络层和数据链路层)的作业。由于与规则相关的原因,我不能直接共享我的大部分代码,但这不应该影响我的问题。我们需要通过使用 shell 脚本创建 node 对象的多个副本(在我的实现中每个副本使用一个用户线程)来运行程序,然后在没有进一步输入的情况下执行。我选择使用 Java,因为我们被告知任何语言都可以用于该项目,而且我不知道我们必须在其上运行它的 Unix 服务器的用户限制(在下面发布)。

这是

ulimit -a

的打印输出
{} ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 1030869
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) 432000
max user processes              (-u) 128
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

例如,这是评分者可以使用的一个示例场景:

node 0 120 5 "Message Sent Over" 30 1 2 &
node 1 120 1 0 2 &
node 2 120 2 0 1 3 4 &
node 3 120 3 2 4 6 &
node 4 120 4 2 3 5 &
node 5 120 5 4 6 &
node 6 120 6 3 5 &

(如果重要,参数格式为 node {id} {duration} {target "Message" sendTime} {neighbors})

现在,在我的 PC 上执行时没有任何错误(使用 IntelliJ 复合测试用例和通过 CMD 运行)。但是,在学校 Unix 服务器上运行时(要求)我在 ~3 个节点后收到以下错误:

{} Error occurred during initialization of VM
java.lang.OutOfMemoryError: unable to create new native thread

从我读到的内容来看,这意味着我已经达到线程限制。在我的机器上这不是问题,我们被告知创建太多线程可能是个问题,但 java 可用于该项目。运行命令

ps huH p <PID_OF_U_PROCESS> | wc -l
产生 ~33(我相信这是该进程的线程数)。在我的 PC 上,每次执行最多使用 11 个线程(使用 VisualVM 发现,除了其中一个线程外,所有线程都是守护线程),虽然比我想要的要多,但可以让我执行我们需要考虑的最艰巨的测试用例。我也没有在整个执行过程中创建额外的线程。该程序始终只使用一个用户线程。

有什么方法可以减少我的罐子使用的线程数吗?只创建了一个用户线程,鉴于学校服务器上对我的用户设置的限制(坦率地说低得离谱),我无法更改,因此生成多个 JVM 似乎正在扼杀我运行代码的能力。

编辑:服务器运行Java 1.8,具体为:

java version "1.8.0_341"
Java(TM) SE Runtime Environment (build 1.8.0_341-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.341-b10, mixed mode)

Edit2:澄清一下,我不是在创建新线程。我的 jar 在执行时以顺序方式运行,从不分叉或创建任何额外的线程。除了用户线程之外的所有线程都是由 Java 创建的,与我的代码或我的操作无关。我正在寻求限制这些线程,因为它们迫使我达到用户限制。

Edit3:我可以分享一些非实现代码(对其他学生没有帮助的东西,但应该有助于理解程序的工作原理)

public static void main(String[] args)
{
    node thisNode = new node(args);
}
//Node constructor
private node(String[] args)                                                                                         //Class constructor
{
    try
    {
        setArgs(args);                                                                                              //Set args appropriately

        network = new Network(id, neighbors);                                                                       //Instantiate network with node id
        
        datalink = new DataLink(network, id);                                                                       //Instantiate datalink with node id and network instance
        network.setDataLink(datalink);                                                                              //Set network's datalink variable to instance of datalink
        
        transport = new Transport(id, network, start, message, destination);                                        //Instantiate transport with node id and network instance
        network.setTransport(transport);                                                                            //Set network's transport variable to instance of transport

        int startingTime = lifetime;
        for (;lifetime != 0; lifetime--)                                                                            //Countdown lifetime to 0
        {
            datalink.receiveFromChannel();                                                                          //Tell datalink layer to read from channels
            transport.sendMessage();                                                                                //Tell transport layer to send messages (if proper time)
            if ((startingTime - lifetime) % 10 == 0)
            {
                network.route(startingTime - lifetime);                                                     //Tell network layer to route according to current time
            }
            Thread.sleep(1000);                                                                             //Sleep 1 second
        }
        transport.outputAllReceived();                                                                              //Output all messages with this node as a destination
    }
    catch (Exception e)
    {
        //System.out.println(e + " in node");
    }
}
java unix ssh java-threads
© www.soinside.com 2019 - 2024. All rights reserved.