Совместимость 32-разрядной и 64-разрядной версий Java

97

Будет ли код Java, созданный и скомпилированный для 32-разрядного JDK в 32-разрядный байт-код, работать в 64-разрядной JVM? Или для 64-битной JVM требуется 64-битный байт-код?

Чтобы дать немного больше подробностей, у меня есть код, который работал в среде Solaris с 32-разрядной JVM, но теперь у меня возникают проблемы после обновления JDK и Weblogic Server до 64-разрядного.

мшафрир
источник
3
уточните пожалуйста "вопросы".
Thorbjørn Ravn Andersen
У меня аналогичная проблема - развертывание приложения Spring на 64-битном сервере weblogic. Мы получаем различные исключения класса «не найден» и другие бесполезные ошибки. Кроме того, он развертывается и работает на некоторых 64-битных машинах, но не на других. Однако мы не можем сказать, что изменилось. Вы это решили?
нет,
2
@nont - какова бы ни была проблема, это не компиляция 32vs64 бит.
Stephen C

Ответы:

94

Да, байт-код Java (и исходный код) не зависят от платформы, если вы используете независимые от платформы библиотеки. 32 против 64 бит не имеет значения.

Зифре
источник
Я столкнулся с этим, когда искал вопрос, который у меня был. Итак, я запустил свое приложение под 32-битной JVM и использовал 64-битную собственную библиотеку. Все прошло нормально. Но когда я запускаю свое приложение под 64-битной JVM и использую 32-битную собственную библиотеку, это терпит неудачу. Как такое могло быть? Просто любопытно.
Уманг Десаи
6
Собственные библиотеки @umangdesai не являются независимыми от платформы библиотеками, поэтому это предположение неверно.
Thorbjørn Ravn Andersen
Означает ли «не имеет значения», что код, скомпилированный с 32-разрядной версией, javacбудет использовать память, доступную с помощью 64-разрядной версии java?
Марк Юний Брут
1
Если вас это ужалило, обратите внимание на собственные библиотеки, которые были объединены в jar-файл, который работает для одной платформы, но не для той, которая вызывает у вас проблемы. (Если вы не понимаете, о чем я говорю, см. Такие вещи: stackoverflow.com/a/14051512/155631 ).
Мэтт С.
21

Я случайно запустил наше (большое) приложение на 64-битной виртуальной машине, а не на 32-битной, и не заметил, пока некоторые внешние библиотеки (вызываемые JNI) не начали давать сбой.

Данные, сериализованные на 32-битной платформе, считывались на 64-битной платформе без каких-либо проблем.

Какие у вас проблемы? Некоторые вещи работают, а другие нет? Вы пробовали прикрепить JConsole и т. Д., И у вас есть пика?

Если у вас очень большая виртуальная машина, вы можете обнаружить, что проблемы с GC в 64-битной версии могут повлиять на вас.

Fortyrunner
источник
1
Вы говорите, что библиотеки JNI не будут работать на 64-битной виртуальной машине, если они 32-битные?
К. Росс
1
Они не работают. Об этом сообщил коллега (что, мягко говоря, показалось мне подозрительным). Мне было интересно, работает ли он на Solaris и что там происходит какое-то молчание. Не было; он ошибся, и он работал под 32bit.
Fortyrunner
У меня была аналогичная проблема с библиотекой JNI. Между 32-битными и 64-битными библиотеками не было совместимости.
Эрик Робертсон
Действительно, ваши библиотеки JNI необходимо заменить. Вероятно, вы можете просто загрузить 64-битную альтернативу с веб-сайта поставщика. (Это помогло мне, для всех библиотек JNI, которые я использовал).
bvdb 03
Это были внутренние библиотеки, и 64-битного эквивалента не было, так что возвращение к 32-битной версии было
приоритетом
11

Да на первый вопрос и нет на второй; это виртуальная машина. Ваши проблемы, вероятно, связаны с неуказанными изменениями в реализации библиотеки между версиями. Хотя это может быть, скажем, состояние гонки.

Есть некоторые препятствия, через которые должна пройти виртуальная машина. В частности, ссылки обрабатываются в файлах классов, как если бы они занимали то же место intв стеке, что и s. doubleи longзанять два отсека для ссылок. Например, поля, виртуальная машина обычно подвергает некоторой перестановке. Все это делается (относительно) прозрачно.

Также некоторые 64-битные JVM используют "сжатые упс". Поскольку данные выравниваются примерно через каждые 8 ​​или 16 байтов, три или четыре бита адреса бесполезны (хотя для некоторых алгоритмов может быть украден бит «метки»). Это позволяет 32-битным адресным данным (таким образом, используя половину полосы пропускания и, следовательно, быстрее) использовать размер кучи 35 или 36 бит на 64-битной платформе.

Том Хотин - tackline
источник
3
Ты удивил меня. Я не думал, что существует такая вещь, как 32-битный байт-код или 64-битный байт-код.
Джон Скит,
3
Перечитывая свой ответ - вы уверены, что имели в виду не наоборот? (Да, тогда нет.)
Джон Скит,
+1 Джону Скиту. Я писал тот же комментарий, но меня перезвонили.
Майкл Майерс
Я имел в виду нет, тогда да, но с вопросами наоборот. Откатили правку и отредактировали (и добавили немного больше информации).
Том Хотин - tackline
4
@Jon Skeet: нет 32-битного и 64-битного байт-кода, но когда JIT выполняется, указатели в JVM (обычно) 32- или 64-битные, в зависимости от платформы. А со сжатым OOPS они могут использовать 32-битные указатели во многих местах, даже на 64-битных JVM. Это значительно экономит память и увеличивает локальность кода, что приводит к большей скорости.
Иоахим Зауэр,
9

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

Не могли бы вы подробнее рассказать о проблеме, с которой столкнулись? Тогда мы сможем вам помочь. В противном случае мы бы просто гадали, в чем проблема.

Питер Лоури
источник
8

Если у вас нет собственного кода (машинный код, скомпилированный для определенной архитектуры), ваш код будет одинаково хорошо работать как в 32-битной, так и в 64-битной JVM.

Однако обратите внимание, что из-за больших адресов (32-разрядная - 4 байта, 64-разрядная - 8 байтов) 64-разрядная JVM потребует больше памяти, чем 32-разрядная JVM для той же задачи.

Торбьёрн Равн Андерсен
источник
Также обратите внимание, что 32-битная JVM в 64-битной системе может иметь больше доступной памяти, чем 32-битная JVM в 32-битной системе, поэтому это может быть интересным вариантом, если у вас есть «использовать несколько ГБ памяти. " применение.
Thorbjørn Ravn Andersen
3

Разница между 32-битными и 64-битными версиями становится более важной, когда вы взаимодействуете с собственными библиотеками. 64-битная Java не сможет взаимодействовать с 32-битной dll, отличной от Java (через JNI)

Джон Томас
источник
5
Вы не ответили на этот очень старый вопрос ничего нового.
Остин Хенли,
0

Java JNI требует библиотек ОС такой же «разрядности», как и JVM. Если вы пытаетесь создать что-то, что зависит, например, от IESHIMS.DLL (находится в% ProgramFiles% \ Internet Explorer), вам нужно использовать 32-битную версию, если ваша JVM 32-битная, и 64-битная версия, если ваша JVM 64-битная. То же самое и для других платформ.

Кроме того, у вас должно быть все готово. Сгенерированный байт-код Java s / b такой же.

Обратите внимание, что для более крупных проектов следует использовать 64-битный компилятор Java, поскольку он может адресовать больший объем памяти.

карпия
источник
-5

йо где не так! На эту тему я написал вопрос оракулу. Ответ был.

«Если вы компилируете свой код на 32-битной машине, ваш код должен работать только на 32-битном процессоре. Если вы хотите запускать свой код на 64-битной JVM, вы должны скомпилировать файлы классов на 64-битной машине, используя 64-битный процессор. -Bit JDK. "

прослойка
источник
5
Формат байтового кода, в который обычно компилируется Java-код, одинаков независимо от 32-битной или 64-битной платформы. Правила различны для любого нативного кода, но байт-код Java переносим.
McDowell
4
Да, похоже, что тот, кто в Oracle отвечал на ваш вопрос, либо неправильно его понял, либо ничего не знал о JVM.
Паоло Эберманн