« | August 2025 | » | 日 | 一 | 二 | 三 | 四 | 五 | 六 | | | | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | | | | | | | |
| 公告 |
戒除浮躁,读好书,交益友 |
Blog信息 |
blog名称:邢红瑞的blog 日志总数:523 评论数量:1142 留言数量:0 访问次数:9693776 建立时间:2004年12月20日 |

| |
[jvm]深入JVM(一):从"abc"=="abc"看java的连接过程 原创空间, 软件技术, 电脑与网络
邢红瑞 发表于 2007/4/24 23:46:22 |
一般说来,我不关注java底层的东西,这次是一个朋友问到了,注意不光是 System.out.println("abc"=="abc");返回true, System.out.println(("a"+"b"+"c").intern()=="abc");也返回true;这和java的连接过程有关。java解析CONSTANT_String_info时,java虚拟机必须把一个字符串对象的引用,放到constant pool entry 中。每个java虚拟机维护着一张列表,里面有所有程序被"interned"的字符串对象的引用。查看constPoolOop.cpp文件oop constantPoolOopDesc::string_at_impl(constantPoolHandle this_oop, int which, TRAPS) { oop entry = *(this_oop->obj_at_addr(which)); if (entry->is_symbol()) { ObjectLocker ol(this_oop, THREAD); if (this_oop->tag_at(which).is_unresolved_string()) { // Intern string symbolOop sym = this_oop->unresolved_string_at(which); entry = StringTable::intern(sym, CHECK_(constantPoolOop(NULL))); this_oop->string_at_put(which, entry); } else { // Another thread beat us and interned string, read string from constant pool entry = this_oop->resolved_string_at(which); } } assert(java_lang_String::is_instance(entry), "must be string"); return entry;}注意有特定字符序列的字符串只会出现一次。如果存在这个Unicode字符序列的字符串,直接返回这个字符串的引用,否则创建新的字符串对象。查看symbolTable.cpp文件oop StringTable::intern(Handle string_or_null, jchar* name, int len, TRAPS) { unsigned int hashValue = hash_string(name, len); int index = the_table()->hash_to_index(hashValue); oop string = the_table()->lookup(index, name, len, hashValue);
// Found if (string != NULL) return string; // Otherwise, add to symbol to table return the_table()->basic_add(index, string_or_null, name, len, hashValue, CHECK_0); }the_table()的定义,SymbolTable* SymbolTable::_the_table = NULL;使用string类的intern()方法,来intern一个字符串,如果具有相同字符序列的字符串被intern过,那末intern()方法直接返回被interned字符串对象的引用。这样的代码 public static final String a="123"; public static final String b="123"; System.out.println(a==b);
返回也是true,如果一个程序多个类使用相同的字符串,这些类的方法使用ldc或者ldc_w把内容为"123"的string对象的引用压入栈。也就是说java虚拟机把所有具有相同字符顺序的字符串处理为同一个java对象。对于任何两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。 从String源码得知这是一个native方法。查看jdk代码JVM_ENTRY(jstring, JVM_InternString(JNIEnv *env, jstring str)) JVMWrapper("JVM_InternString"); JvmtiVMObjectAllocEventCollector oam; if (str == NULL) return NULL; oop string = JNIHandles::resolve_non_null(str); oop result = StringTable::intern(string, CHECK_0); return (jstring) JNIHandles::make_local(env, result);JVM_END也调用了StringTable::intern。 本文参考了小钢翻译深入java虚拟机,又给他捐款了,不知道他包养超女MM的钱够了没有。 |
|
回复:深入JVM(一):从"abc"=="abc"看java的连接过程 原创空间, 软件技术, 电脑与网络
wueddie(游客)发表评论于2007/9/19 21:34:12 |
|
回复:深入JVM(一):从"abc"=="abc"看java的连接过程 原创空间, 软件技术, 电脑与网络
nurhachi(游客)发表评论于2007/4/25 17:38:57 |
|
» 1 »
|