Почему Java socket.connect () потребляет 100% ресурсов процессора? - PullRequest
5 голосов
/ 05 июня 2010

Я создал пул потоков и дал ему 50 задач для подключения к серверу. Так что, как только было сделано соединение, отправка некоторых данных, а затем отключение. У него также есть тайм-аут чтения, установленный на 5 секунд (конечно, 5000). Я даже установил максимальный размер пула потоков, равный 1. Затем я запустил это на linux и запустил htop (лучшая версия top), чтобы проверить загрузку процессора. Я постоянно видел одно из моих ядер (двухъядерный компьютер) на 100% все время. Я профилировал это с помощью hprof (-agentlib:hprof=cpu=samples,interval=20,depth=3) и имел socket.connect () на 99%.

Вот что я нахожу странным, разве смысл блокировать ввод-вывод для блокировки (а значит, ждать)? Мой JDK (от java -version):

OpenJDK Runtime Environment (IcedTea6 1.6.1) (6b16-1.6.1-3ubuntu3)

OpenJDK Server VM (build 14.0-b16, mixed mode)

Обновление1 : такая же проблема возникает и в JVM от Sun:

java -version
Java version "1.6.0_20"

Update2 : Это связано с методом doConnect, который является собственным. Кто-нибудь знает, как я могу просмотреть исходный код для этого собственного кода / C?

Update3 : Я вошел в Windows, чтобы написать код и проверить его. Все работало нормально, ресурсы ЦП не использовались. Я снова вхожу в Linux, и теперь проблема все еще здесь, но не настолько серьезная, чтобы затянуть все ядро ​​процессора на 100% всего за 1 соединение .... Вот код:

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Vector;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


public class SocketTest {


    public static void main(String[] args) {
        new SocketTest();

    }

    public SocketTest() {

        ThreadPoolExecutor tpe = (ThreadPoolExecutor) Executors.newFixedThreadPool(40);

        Vector<Callable<Object>> tasks = new Vector<Callable<Object>>();

        for (int i = 0; i < 1500; i++)
            tpe.submit(new Thread() {

                public void run() {
                    byte[] ip = { 74, 125, 19, (byte)((Math.random()*253)+1)};
                    Socket socket = new Socket();
                    try {
                        System.out.println("new thread: "+ip[3]);
                        socket.connect(new InetSocketAddress(InetAddress.getByAddress(ip), 80), 3000);
                        socket.close();
                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        //no need to print
                    }
                }
            });

            try {
                tpe.invokeAll(tasks);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
            System.out.println("test");
            try {
                //too lazy to write actual code to wait for task completness...
                tpe.awaitTermination(9001, TimeUnit.DAYS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("test2");
    }

}

Ответы [ 2 ]

0 голосов
/ 25 декабря 2013

Оставляя в стороне проблемы проектирования с кодом (например, tasks никогда не используется), я не смог воспроизвести высокую загрузку ЦП ни в Windows, ни в Ubuntu (12.04.2 LTS).

Можете ли вы обновить JDK до 1,7 (sudo apt-get install openjdk-7-jdk) и сообщить мне, какую версию JDK вы используете? Например, у меня javac 1.7.0_25 (получил javac -version)

Я постараюсь выкопать дальше после этого ...

0 голосов
/ 23 июля 2010

Я просто хотел прокомментировать, что похоже, что вы злоупотребляете пулом потоков, так как вы на самом деле создаете новые объекты типа Thread 1500 раз, только чтобы передать их в пул потоков, который создает больше потоков для запуска вашего задачи. Обычно вы должны создать экземпляр Runnable и позволить пулу потоков выполнить свою работу. Я не говорю, что это то, что заставляет процессор задыхаться, но это неприемлемая проблема.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...