我已经阅读了这个问题的一些答案(为什么我不能创建大尺寸的数组https://bugs.openjdk.java.net/browse/JDK-8029587)我不理解以下内容。“在GC代码中,我们将对象的大小以单词的形式传递为int。”据我所知,JVM中单词的大小为4字节。根据这一点,如果我们将单词中的大尺寸长数组(例如MAX_INT-5)的大小作为INT传递,我们必须获得OutOfMemoryException,请求的数组大小超过VM限制,因为即使没有标头大小,对于INT来说,大小也太大。那么,为什么不同类型的数组对元素的最大数量有相同的限制呢?
据我所知,答案在jdk源代码中(我正在查看jdk-9);在写了之后,我也不确定是否应该改为评论(如果它回答了你的问题),但评论太长了。。。
首先,从hotspot/src/share/vm/oops/arrayKlass.cpp
抛出错误:
if (length > arrayOopDesc::max_array_length(T_ARRAY)) {
report_java_out_of_memory("Requested array size exceeds VM limit");
....
}
现在,T_ARRAY
实际上是基本类型的
枚举,如下所示:
public static final BasicType T_ARRAY = new BasicType(tArray);
// tArray is an int with value = 13
这是第一个表明,当计算最大大小时,jdk不关心该数组将容纳什么(T_array
没有指定该数组将包含什么类型)。
现在实际验证最大数组大小的方法如下所示:
static int32_t max_array_length(BasicType type) {
assert(type >= 0 && type < T_CONFLICT, "wrong type");
assert(type2aelembytes(type) != 0, "wrong type");
const size_t max_element_words_per_size_t =
align_size_down((SIZE_MAX/HeapWordSize - header_size(type)), MinObjAlignment);
const size_t max_elements_per_size_t =
HeapWordSize * max_element_words_per_size_t / type2aelembytes(type);
if ((size_t)max_jint < max_elements_per_size_t) {
// It should be ok to return max_jint here, but parts of the code
// (CollectedHeap, Klass::oop_oop_iterate(), and more) uses an int for
// passing around the size (in words) of an object. So, we need to avoid
// overflowing an int when we add the header. See CRs 4718400 and 7110613.
return align_size_down(max_jint - header_size(type), MinObjAlignment);
}
return (int32_t)max_elements_per_size_t;
}
我没有深入研究代码,但它是基于HeapWordSize
;至少为8字节
。这里有一个很好的参考(我试图查找代码本身,但对它的引用太多了)。
只解决为什么不同类型的数组对最大元素数有相同的限制?零件:
因为在实际现实中没多大关系;但是允许实现JVM的代码更简单。
当只有一个限制时;这对于所有类型的数组都是一样的;然后您可以使用该代码处理所有数组。而不是有很多特定于类型的代码。
考虑到需要“大”数组的人仍然可以创建它们;只有那些需要真正非常大的数组的人才会受到影响;为什么要花这么多精力?
我正在学习罗伯特·C·马丁(Robert C.Martin)2009年出版的《干净的代码》(Clean Code)一书,我偶然发现了衔接的概念(第10章)。罗伯特引用: 每个方法使用每个变量的类具有最大的内聚性。一般来说,创建这样的最大内聚类既不可取,也不可能。。。 不幸的是,我没有找到详细的解释。有没有人用真实的代码示例来解释这一点? 非常感谢!!
为什么不可能创建最大int大小的数组? 我找到了这样的解释: null
问题内容: 我想做的是这样的: Eclipse中给了我这个编译错误的:。 当我将类设为静态时,该错误消失。我可以使static,但我不明白为什么我不能在内部类中声明一个。 问题答案: 定义为嵌套类型的类型始终是隐式的(请参见JLS§8.9。Enums) 您不能在非静态类型(也就是“内部类”,请参见JLS§8.1.3。内部类和封闭实例)中拥有静态嵌套类型。 因此,您不能在非静态嵌套类型中包含内部类型
问题内容: 这是我正在运行的命令: 另外,我正在使用自制Python运行Mac 这是我的setup.py脚本:https : //gist.github.com/cloudformdesign/4791c46fe7cd52eb61cd 我要疯了-我不知道为什么这不起作用。 问题答案: 首先安装软件包: 文档并不太清楚,但是 “ wheel项目为setuptools提供了bdist_wheel命令”
问题内容: Java中的数组的长度是固定的。Java为什么要允许大小为0的数组呢? 问题答案: 它表示它为空。即您可以遍历它,就好像它有项目并且没有结果发生一样: 从而避免了检查的需要。如果所讨论的数组为,则会发生异常,但是在这种情况下,它什么也不做,这可能是适当的。
我试图创建一个带有可选参数的模板函数,但我很难理解编译失败的原因。这是我的测试(设计)代码: 只有当我用这两个参数调用时,代码才会编译。如果我尝试只传递1个参数,编译将失败,出现以下错误: main.cpp:18:34:错误:调用'GetCountIf' std::cout<<“numelements=”< (我用的是C++14)