64-битная Java VM работает в 10 раз медленнее - PullRequest
8 голосов
/ 02 декабря 2009

У меня есть приложение Java, которое упаковано с использованием JarBundler. Приложение довольно сильно загружает процессор (много больших вызовов Collection.sort ()).

В Mac OS приложение работает медленно и вяло при использовании 64-битной JavaApplicationStub. Этот файл JavaApplicationStub запускает 64-разрядную виртуальную машину Java.

Я нашел старый файл JavaApplicationStub, который является только 32-битным. Я заменил его в Bundle, и приложение работает в 10 раз быстрее! (следовательно, 32-разрядная виртуальная машина используется при запуске приложения).

Имеет ли это какой-то смысл? Почему 64-битная виртуальная машина намного медленнее? Имеет ли смысл создавать приложение и взламывать файл JavaApplicationStub, как этот?

Консультации приветствуются.

Ответы [ 2 ]

5 голосов
/ 02 декабря 2009

См. в этом посте о преимуществах / недостатках работы 64-битной JVM. В целом, разыменование указателя и перераспределение памяти может занять больше времени - и вы перемещаетесь по большим структурам данных (т.е. 64, а не 32-битным, что не дает вам никаких преимуществ, если вы не используете их просто).

Также см. эту соответствующую статью , где обсуждается снижение производительности до 85% при переходе на 64-битную версию, что соответствует тому, что вы испытываете:

Причина такого снижения производительности на самом деле очень сильно связана с увеличением памяти. Ссылки на память под оболочками Java стали в два раза больше, увеличивая размер структур памяти во время выполнения WAS и объектов вашего приложения. К сожалению, размеры кэш-памяти процессора не увеличивались одновременно. Это означает, что больше кэш-памяти теряется, что означает более загруженную работу для оборудования, занимающегося большим объемом памяти, что означает более низкую производительность приложения.

0 голосов
/ 28 января 2014

64 бит не медленнее. Попробуйте:

public class Benchmark {
public static void main(String args[]) {
long time = System.currentTimeMillis();
for (int a = 1; a < 900000000; a++) {
    for (int b = 1; b < 20; b++) {
    }
}
long time2 = System.currentTimeMillis() - time;
System.out.println("\nTime counter stopped: " + time2);

}

в 32 и 64 и сообщите нам, какие результаты вы получите

...