【问题标题】:How to create more than Integer.MAX_VALUE objects in a jvm?如何在 jvm 中创建多个 Integer.MAX_VALUE 对象?
【发布时间】:2015-02-23 22:06:09
【问题描述】:

从这个discussion我需要编写一个程序来知道问题的答案:“如果有比int的最大值更多的对象,那么jvm将什么分配给一个对象的地址?”,

在 eclipse.ini 中使用以下设置

-startup
plugins/org.eclipse.equinox.launcher_1.3.0.v20130327-1440.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.1.200.v20131025-1931
-product
org.eclipse.epp.package.jee.product
--launcher.defaultAction
openFile
--launcher.XXMaxPermSize
256M
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
256m
--launcher.defaultAction
openFile
--launcher.appendVmargs
-vmargs
-Dosgi.requiredJavaVersion=1.6
-Xms6144m
-Xmx6144m

及以下程序,

class SubClass {
    int x = 4;
    int getX(){
        return x;
    }
}

    public class Dummy2 {

        public static void main(String[] args){

            SubClass obj[] = null;
            obj = new SubClass[Integer.MAX_VALUE];
            for(int i = 0; i < Integer.MAX_VALUE; i++){
                obj[i] = new SubClass();
            }

            SubClass objRef1 = new SubClass();
            System.out.println(objRef1);
            System.out.println(objRef1.hashCode());

            SubClass objRef2 = new SubClass();
            System.out.println(objRef2);
            System.out.println(objRef2.hashCode());




        }

    }

出现错误:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

我的目标是查看对象地址的值以及为最后两个对象生成的哈希码。

我使用在 64 位 Windows 7 操作系统上运行的 64 位 jvm,它为每个本机用户级进程提供 8TB 的虚拟空间。硬件有 8GB RAM 芯片。

请帮帮我!!

【问题讨论】:

  • 可能不相关,但您可能应该在 程序 的 VM 参数(即运行配置)中指定最大堆大小,而不是在 eclipse 文件中。跨度>
  • “对象的内部地址”是什么意思?
  • @RealSkeptic 没什么意思,我删掉了那个词):现在,你能帮我回答吗?

标签: java memory-management jvm heap-memory


【解决方案1】:

这里有很多误解。

  • Object.hashCode() 是一个随机生成的数字,存储在对象的标头中,并且在对象移动时不会改变。
  • Windows 不允许 JVM 使用虚拟内存,您无法创建大于主内存的 JVM 堆。
  • 20 亿个元素至少需要 20 GB 的 JVM 内存。
  • 一个数组不能有超过 Integer.MAX_VALUE 个元素,但可以有一个数组数组(或数组,数组)

我的目标是查看对象内部地址的值以及为最后两个对象生成的哈希码。

它们是随机的,因此它们与第一个元素之间没有区别。

【讨论】:

  • Windows doesn't allow the JVM to use virtual memory, you can't create a JVM heap which is larger than main memory. 你确定吗? msdn.microsoft.com/en-us/library/windows/desktop/…
  • @overexchange 如果您愿意,可以尝试一下,看看会发生什么;)
  • 试试什么?你是在建议一些日食设置吗?
  • @overexchange 我并不是说过度提交托管内存也适用于 Linux。不同之处在于,在 linux 上它可能会锁定,您可以终止该进程。在 Windows 上,您更有可能需要重启电源。无论哪种方式,您都不希望堆超过大约 80% 的主内存。
  • 我不在乎 RAM 芯片是不是 4GB 芯片,这就是我想说的
【解决方案2】:

我假设您询问的是 this

您不一定需要创建多个 Integer.MAX_VALUE 对象。您只需要创建一些直到发生碰撞。你可以相对容易地做到这一点。

public static void main(String[] args) throws Exception {
    final int LENGTH = Integer.MAX_VALUE / 256;
    Object[] values = new Object[LENGTH];
    int count = 0;
    for (int i = 0; i < Integer.MAX_VALUE; i++) {
        Object o = new Object();
        int hashCode = o.hashCode();
        if (hashCode > LENGTH)
            continue;
        if (values[hashCode] != null) {
            System.out.println("found after " + count + ": " + values[hashCode] + " same hashcode as " + o);
            System.out.println(values[hashCode] == o);
            System.exit(0);
        } else {
            System.out.println(hashCode);
            values[hashCode] = o;
            count++;
        }
    }
}

例如,在我的机器上,这会在 4712 个 hashCode 小于 Integer.MAX_VALUE / 256 的新实例之后停止。这意味着两个不符合 GC 条件的 Object 实例具有相同的 hashCode

以上印刷品

...
5522036
4166797
5613746
found after 4712: java.lang.Object@6aca04 same hashcode as java.lang.Object@6aca04
false

【讨论】:

  • 在我的机器上,上面的程序总是显示:java.lang.ArrayIndexOutOfBoundsException: 8388607,它是 intmax/256,我现在正在尝试使用 intmax/8。你用 64 位 jvm 运行吗?
  • @overexchange 使用上面的确切代码?您应该受到if (hashCode &gt; LENGTH) 的保护。
  • @overexchange 是的,64 位 JVM。调整LENGTH 以适应您可用的内存量。
  • Object[] values = new Object[LENGTH]; 给这些对象的哈希码可以大于 LENGTH 的值,对吗?所以我仍然不清楚条件(hashCode > LENGTH)
  • @overexchange 为了您不会耗尽内存,我们设置了一个较小的LENGTH。但是,hashCode 可以返回比LENGTH 更大的值。如果我们看到这样的hashCode,我们就跳过它。这就是为什么我放了一个continue
猜你喜欢
  • 1970-01-01
  • 2021-11-22
  • 2023-03-18
  • 1970-01-01
  • 2017-02-03
  • 1970-01-01
  • 2012-09-16
  • 1970-01-01
  • 2012-05-19
相关资源
最近更新 更多