Kompatybilność z technologią Java w wersji 32-bitowej i 64-bitowej

97

Czy kod Java zbudowany i skompilowany na 32-bitowym JDK do 32-bitowego kodu będzie działał w 64-bitowej JVM? A może 64-bitowa maszyna JVM wymaga 64-bitowego kodu bajtowego?

Aby dać trochę więcej szczegółów, mam kod, który działał w środowisku Solaris z 32-bitową maszyną JVM, ale teraz pojawiają się problemy po aktualizacji JDK i serwera Weblogic do wersji 64-bitowej.

mshafrir
źródło
3
prosimy o wyjaśnienie „problemów”.
Thorbjørn Ravn Andersen
Mam podobny problem - wdrażam aplikację Spring na 64-bitowym serwerze weblogic. Otrzymujemy różne wyjątki klasy nie znaleziono i inne nieprzydatne błędy. Ponadto wdraża się i działa na niektórych komputerach 64-bitowych, ale nie na innych. Nie możemy jednak powiedzieć, co jest innego. Czy rozwiązałeś to?
nie
2
@nont - bez względu na problem, nie jest to kompilacja 32vs64 bit.
Stephen C

Odpowiedzi:

94

Tak, kod bajtowy Java (i kod źródłowy) jest niezależny od platformy, przy założeniu, że używasz bibliotek niezależnych od platformy. 32 i 64 bit nie powinny mieć znaczenia.

Zifre
źródło
Natknąłem się na to, szukając pytania, które miałem. Więc uruchomiłem moją aplikację na 32-bitowej JVM i użyłem 64-bitowej biblioteki natywnej. To działało dobrze. Ale kiedy uruchamiam aplikację na 64-bitowej maszynie JVM i używam 32-bitowej biblioteki natywnej, kończy się to niepowodzeniem. Jak to możliwe? Po prostu ciekawy.
Umang Desai
6
Biblioteki natywne @umangdesai nie są bibliotekami niezależnymi od platformy, dlatego założenie nie jest aktualne.
Thorbjørn Ravn Andersen
Czy „nie powinno mieć znaczenia” oznacza, że ​​kod skompilowany w wersji 32-bitowej javacbędzie korzystał z pamięci udostępnionej w wersji 64-bitowej java?
Marcus Junius Brutus
1
Jeśli cię to ukąszy, uważaj na natywne biblioteki, które zostały spakowane w słoik, który działa dla jednej platformy, ale nie dla tej, która powoduje problemy. (Jeśli nie masz pojęcia, o czym mówię, zobacz takie rzeczy: stackoverflow.com/a/14051512/155631 ).
Matt S.,
21

Przypadkowo uruchomiłem naszą (dużą) aplikację na 64-bitowej maszynie wirtualnej, a nie na 32-bitowej maszynie wirtualnej, i nie zauważyłem, dopóki niektóre zewnętrzne biblioteki (wywołane przez JNI) nie zaczęły ulegać awarii.

Dane serializowane na platformie 32-bitowej zostały wczytane na platformie 64-bitowej bez żadnych problemów.

Jakie masz problemy? Czy niektóre rzeczy działają, a inne nie? Czy próbowałeś dołączyć JConsole itp. I masz szczyt?

Jeśli masz bardzo dużą maszynę wirtualną, może się okazać, że problemy z GC w wersji 64-bitowej mogą wpływać na Ciebie.

Fortyrunner
źródło
1
czy mówisz, że biblioteki JNI nie będą działać na 64-bitowych maszynach wirtualnych, jeśli są 32-bitowe?
C. Ross
1
Nie działają. Kolega zgłosił, że tak (co wydało mi się podejrzane - delikatnie mówiąc). Zastanawiałem się, czy jeździ na Solarisie i że coś tam się dzieje. Nie było; pomylił się i działał pod 32-bitowym.
Fortyrunner
Miałem podobny problem z biblioteką JNI. Nie było kompatybilności między bibliotekami 32-bitowymi i 64-bitowymi.
Erick Robertson
Rzeczywiście, twoje biblioteki JNI wymagają wymiany. Prawdopodobnie możesz po prostu pobrać wersję 64-bitową ze strony internetowej dostawcy. (To załatwiło sprawę w przypadku wszystkich bibliotek JNI, z których korzystałem).
bvdb
Były to biblioteki wewnętrzne i żaden odpowiednik 64-bitowy nie był dostępny, więc powrót do wersji 32-bitowej był na porządku dziennym ..
Fortyrunner
11

Tak na pierwsze pytanie i nie na drugie pytanie; to maszyna wirtualna. Twoje problemy są prawdopodobnie związane z nieokreślonymi zmianami w implementacji biblioteki pomiędzy wersjami. Chociaż może to być, powiedzmy, stan wyścigu.

Maszyna wirtualna musi przejść przez kilka przeszkód. W szczególności odwołania są traktowane w plikach klas tak, jakby zajmowały tyle samo miejsca co ints na stosie. doublei longzajmij dwa sloty referencyjne. Na przykład pola, istnieje pewna rearanżacja, przez którą zwykle przechodzi VM. Wszystko to odbywa się (względnie) przejrzyście.

Również niektóre 64-bitowe maszyny JVM używają „skompresowanych błędów”. Ponieważ dane są wyrównane co około 8 lub 16 bajtów, trzy lub cztery bity adresu są bezużyteczne (chociaż w przypadku niektórych algorytmów może zostać skradziony bit „znacznika”). Dzięki temu 32-bitowe dane adresowe (a zatem wykorzystujące o połowę mniej przepustowości, a tym samym szybsze) mogą używać rozmiarów sterty 35- lub 36-bitowych na platformie 64-bitowej.

Tom Hawtin - haczyk
źródło
3
Zaskakujesz mnie. Nie sądziłem, że istnieje coś takiego jak kod 32-bitowy lub 64-bitowy.
Jon Skeet
3
Ponownie czytając swoją odpowiedź - czy na pewno nie miałeś tego na myśli na odwrót? (Tak, potem nie)
Jon Skeet
+1 dla Jona Skeeta. Pisałem ten sam komentarz, ale zostałem wezwany.
Michael Myers
Miałem na myśli nie, a potem tak, ale z pytaniami na odwrót. Wycofałem edycję i zredagowałem (i umieściłem trochę więcej informacji).
Tom Hawtin - tackline
4
@Jon Skeet: nie ma 32-bitowego i 64-bitowego kodu bajtowego, ale po JIT, wskaźniki w JVM są (zwykle) 32 lub 64 bitowe, w zależności od platformy. Dzięki skompresowanym OOPS mogą używać wskaźników 32-bitowych w wielu miejscach, nawet w 64-bitowych maszynach JVM. Oszczędza to sporo pamięci i zwiększa lokalność kodu, prowadząc w ten sposób do większej szybkości.
Joachim Sauer
9

Cały kod bajtowy jest oparty na 8 bitach. (Dlatego nazywa się to kodem BYTE) Wszystkie instrukcje są wielokrotnością 8-bitów. Tworzymy na maszynach 32-bitowych, a nasze serwery uruchamiamy na 64-bitowej JVM.

Czy mógłbyś szczegółowo opisać problem, z którym się borykasz? Wtedy będziemy mieli szansę ci pomóc. W przeciwnym razie po prostu zgadywalibyśmy, jaki masz problem.

Peter Lawrey
źródło
8

Jeśli nie masz kodu natywnego (kod maszynowy skompilowany dla konkretnej architektury arkusza), Twój kod będzie działał równie dobrze w 32-bitowej i 64-bitowej JVM.

Należy jednak pamiętać, że ze względu na większe adresy (32-bitowa to 4 bajty, 64-bitowa to 8 bajtów) 64-bitowa maszyna JVM będzie wymagała więcej pamięci niż 32-bitowa JVM do tego samego zadania.

Thorbjørn Ravn Andersen
źródło
Należy również pamiętać, że 32-bitowa maszyna JVM w systemie 64-bitowym może mieć więcej dostępnej pamięci niż 32-bitowa JVM w systemie 32-bitowym, więc może to być interesująca opcja, jeśli masz opcję „użyj kilku GB pamięci " podanie.
Thorbjørn Ravn Andersen
3

Różnica między wersjami 32-bitowymi a 64-bitowymi staje się coraz ważniejsza, gdy łączysz się z bibliotekami natywnymi. 64-bitowa Java nie będzie mogła współpracować z 32-bitową biblioteką DLL inną niż Java (przez JNI)

John Thomas
źródło
5
Nie podałeś nic nowego na to bardzo stare pytanie.
Austin Henley,
0

Java JNI wymaga bibliotek systemu operacyjnego o tej samej „zaciekłości” co JVM. Jeśli spróbujesz zbudować coś, co zależy, na przykład, od IESHIMS.DLL (znajduje się w% ProgramFiles% \ Internet Explorer), musisz wybrać wersję 32-bitową, gdy Twoja maszyna JVM jest 32-bitowa, wersję 64-bitową, gdy JVM jest 64-bitowa. To samo dotyczy innych platform.

Poza tym wszystko powinno być gotowe. Wygenerowany kod bajtowy Java s / b jest taki sam.

Zauważ, że powinieneś używać 64-bitowego kompilatora Java do większych projektów, ponieważ może on zająć więcej pamięci.

karpia
źródło
-5

yo, gdzie źle! W tym temacie napisałem pytanie do wyroczni. Odpowiedź brzmiała.

„Jeśli kompilujesz kod na maszynie 32-bitowej, Twój kod powinien działać tylko na procesorze 32-bitowym. Jeśli chcesz uruchomić kod na 64-bitowej maszynie JVM, musisz skompilować klasę Files na maszynie 64-bitowej przy użyciu -Bit JDK. "

elayer
źródło
5
Format kodu bajtowego kodu Java jest zwykle zestawiane do jest taka sama bez względu na platformach 32-bitowych lub 64-bitowych. Reguły są różne dla każdego kodu natywnego, ale kod bajtowy Java jest przenośny.
McDowell
4
Tak, wygląda na to, że ktokolwiek w Oracle odpowiadał na twoje pytanie albo źle je zrozumiał, albo nie wiedział nic o JVM.
Paŭlo Ebermann