【发布时间】:2012-06-26 15:08:51
【问题描述】:
在关于 JVM 基于 char[] 实现字符串创建方式的问题之后,我提到当 char[] 被复制到新字符串的内部时不会发生迭代,因为 System.arraycopy 得到最终调用,它使用诸如 memcpy 之类的函数在本机的、依赖于实现的级别 (the original question) 复制所需的内存。
我想亲自检查一下,所以我下载了 Openjdk 7 源代码并开始浏览它。
我在 OpenJDK C++ 源代码中找到了 System.arraycopy 的实现,在openjdx/hotspot/src/share/vm/oops/objArrayKlass.cpp:
if (stype == bound || Klass::cast(stype)->is_subtype_of(bound)) {
// elements are guaranteed to be subtypes, so no check necessary
bs->write_ref_array_pre(dst, length);
Copy::conjoint_oops_atomic(src, dst, length);
} else {
// slow case: need individual subtype checks
如果元素不需要类型检查(例如,原始数据类型数组就是这种情况),则调用 Copy::conjoin_oops_atomic。
Copy::conjoint_oops_atomic 函数位于“copy.hpp”中:
// overloaded for UseCompressedOops
static void conjoint_oops_atomic(narrowOop* from, narrowOop* to, size_t count) {
assert(sizeof(narrowOop) == sizeof(jint), "this cast is wrong");
assert_params_ok(from, to, LogBytesPerInt);
pd_conjoint_jints_atomic((jint*)from, (jint*)to, count);
}
现在我们依赖于平台,因为复制操作有不同的实现,基于操作系统/架构。我将以 Windows 为例。 openjdk\hotspot\src\os_cpu\windows_x86\vm\copy_windows_x86.inline.hpp:
static void pd_conjoint_oops_atomic(oop* from, oop* to, size_t count) {
// Do better than this: inline memmove body NEEDS CLEANUP
if (from > to) {
while (count-- > 0) {
// Copy forwards
*to++ = *from++;
}
} else {
from += count - 1;
to += count - 1;
while (count-- > 0) {
// Copy backwards
*to-- = *from--;
}
}
}
而且...令我惊讶的是,它遍历元素(oop 值),一一复制它们(似乎)。有人可以通过遍历数组中的元素来解释为什么即使在本机级别也可以完成复制吗?
【问题讨论】: