【问题标题】:Java 32-bit vs 64-bit compatibilityJava 32 位与 64 位兼容性
【发布时间】:2010-10-21 11:38:04
【问题描述】:

针对 32 位 JDK 构建和编译成 32 位字节码的 Java 代码能否在 64 位 JVM 中工作?还是 64 位 JVM 需要 64 位字节码?

为了提供更多细节,我的代码在运行 32 位 JVM 的 Solaris 环境中运行,但现在我在将 JDK 和 Weblogic Server 升级到 64 位后遇到了问题。

【问题讨论】:

  • 请澄清“问题”。
  • 我遇到了类似的问题 - 在 64 位 weblogic 服务器上部署 spring 应用程序。我们得到各种类未找到异常和其他无用的错误。此外,它在一些 64 位机器上部署和运行,但不是在其他机器上。然而,我们无法说出有什么不同。你解决了吗?
  • @nont - 不管是什么问题,都不是 32vs64 位编译。

标签: java jvm 64-bit compatibility 32-bit


【解决方案1】:

是的,假设您使用独立于平台的库,Java 字节码(和源代码)是独立于平台的。 32 位与 64 位无关紧要。

【讨论】:

  • 我在搜索我遇到的问题时遇到了这个问题。所以我在 32 位 JVM 下运行我的应用程序并使用 64 位本机库。它运行良好。但是当我在 64 位 JVM 下运行我的应用程序并使用 32 位本机库时,它会失败。这怎么可能?只是好奇。
  • @umangdesai 本地库不是独立于平台的库,因此假设不成立。
  • “不应该”是否意味着使用 32 位 javac 编译的代码将利用 64 位 java 提供的内存?
  • 如果您对此感到厌烦,请注意已捆绑到适用于一个平台的 jar 中的本机库,但不适用于给您带来问题的平台。 (如果您不知道我指的是什么,请参阅以下内容:stackoverflow.com/a/14051512/155631)。
【解决方案2】:

第一个问题是,第二个问题不是;它是一个虚拟机。您的问题可能与版本之间库实现的未指定更改有关。虽然它可能是一个竞争条件。

VM 必须经历一些障碍。值得注意的是,引用在类文件中被视为与堆栈上的ints 占用相同的空间。 doublelong 占用两个引用槽。例如字段,VM 通常会进行一些重新排列。这一切都是(相对)透明地完成的。

还有一些 64 位 JVM 使用“压缩 oops”。因为数据大约每 8 或 16 个字节对齐一次,所以地址的 3 或 4 位是无用的(尽管某些算法可能会窃取“标记”位)。这允许 32 位地址数据(因此使用一半的带宽,因此速度更快)在 64 位平台上使用 35 位或 36 位的堆大小。

【讨论】:

  • 你让我吃惊。我不认为有 32 位字节码或 64 位字节码之类的东西。
  • 重读您的答案 - 您确定您的意思不是反过来吗? (是然后不是。)
  • +1 给 Jon Skeet。我正在写同样的评论,但被叫走了。
  • 我的意思是不,然后是,但问题反过来。已回滚编辑并进行了编辑(并添加了更多信息)。
  • @Jon Skeet:没有 32 位和 64 位字节码,但是当 JITed 时,JVM 中的指针(通常)是 32 位或 64 位,具体取决于平台。借助 Compressed OOPS,他们可以在许多地方使用 32 位指针,甚至在 64 位 JVM 上也是如此。这样可以节省大量内存并增加代码局部性,从而提高速度。
【解决方案3】:

我不小心在 64 位 VM 而不是 32 位 VM 上运行了我们的(大型)应用程序,直到一些外部库(由 JNI 调用)开始失败时才注意到。

在 32 位平台上序列化的数据在 64 位平台上读取完全没有问题。

您遇到了哪些问题?有些事情有效,有些无效?您是否尝试过附加 JConsole 等并有一个高峰?

如果您有一个非常大的 VM,您可能会发现 64 位的 GC 问题会影响您。

【讨论】:

  • 你是说如果 JNI 库是 32 位的,它们就不能在 64 位 VM 中工作?
  • 它们不起作用。一位同事报告说他们这样做了(我觉得这很可疑——至少可以这么说)。我想知道他是否在 Solaris 上运行,并且正在发生某种类型的 thunking。没有;他弄错了,它在 32 位下运行。
  • 我在 JNI 库中遇到过类似的问题。 32 位和 64 位库之间不兼容。
  • 确实,您的 JNI 库需要更换。您可能只需从供应商的网站下载 64 位替代方案。 (这对我有用,对于我使用的所有 JNI 库)。
  • 这些是内部库,没有可用的 64 位等效库,所以回到 32 位是当务之急..
【解决方案4】:

所有字节码都是基于 8 位的。 (这就是为什么它被称为 BYTE 代码)所有指令的大小都是 8 位的倍数。 我们在 32 位机器上开发并使用 64 位 JVM 运行我们的服务器。

您能否详细说明您所面临的问题?那么我们可能有机会帮助你。否则我们只会猜测您遇到了什么问题。

【讨论】:

    【解决方案5】:

    除非您有本机代码(为特定架构编译的机器代码),否则您的代码将在 32 位和 64 位 JVM 中同样运行良好。

    但是请注意,由于地址更大(32 位是 4 个字节,64 位是 8 个字节),对于相同的任务,64 位 JVM 将需要比 32 位 JVM 更多的内存。

    【讨论】:

    • 另外请注意,64 位系统上的 32 位 JVM 可能比 32 位系统上的 32 位 JVM 有更多可用内存,因此如果您有一个“使用几 GB 内存”的应用程序。
    【解决方案6】:

    在创建 exe 时在配置中添加如下参数

    http://www.technimi.com/index.php?do=/group/java/forum/building-an-exe-using-launch4j-for-32-bit-jvm/

    希望对你有帮助。

    谢谢...

    /jav

    【讨论】:

      【解决方案7】:

      哟哪里错了!针对这个主题,我向 oracle 写了一个问题。答案是。

      “如果你在 32 位机器上编译你的代码,你的代码应该只能在 32 位处理器上运行。如果你想在 64 位 JVM 上运行你的代码,你必须在 64 位机器上编译你的类文件使用 64 位 JDK。”

      【讨论】:

      • byte code format Java 代码通常编译为相同,无论 32 位还是 64 位平台。 任何本机代码的规则都不同,但 Java 字节码是可移植的。
      • 是的,看起来 Oracle 的任何人在回答您的问题时要么误解了它,要么对 JVM 一无所知。
      【解决方案8】:

      当您与本机库交互时,32 位与 64 位的区别确实变得更加重要。 64 位 Java 将无法与 32 位非 Java dll 交互(通过 JNI)

      【讨论】:

      • 您没有为这个非常古老的问题提供任何新内容。
      【解决方案9】:

      Java JNI 需要与 JVM 一样“琐碎”的操作系统库。例如,如果您尝试构建依赖于 IESHIMS.DLL(位于 %ProgramFiles%\Internet Explorer 中)的东西,则当您的 JVM 为 32 位时,您需要使用 32 位版本,当您的 JVM 为 64 位时,您需要使用 64 位版本。其他平台也是如此。

      除此之外,您应该已准备就绪。生成的 Java 字节码 s/b 相同。

      请注意,对于较大的项目,您应该使用 64 位 Java 编译器,因为它可以处理更多内存。

      【讨论】:

        猜你喜欢
        • 2023-03-30
        • 2016-02-28
        • 1970-01-01
        • 2013-10-21
        • 1970-01-01
        • 2013-03-12
        • 2019-08-19
        • 2012-02-11
        • 2010-11-27
        相关资源
        最近更新 更多