[jvm]深入JVM(一):从"abc"=="abc"看java的连接过程
来源:互联网 发布:java snmp4j jar 编辑:程序博客网 时间:2024/06/05 20:35
一般说来,我不关注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。
- [jvm]深入JVM(一):从"abc"=="abc"看java的连接过程
- 从JVM Instructions看Java
- 从JVM Instructions看Java
- Java基础---对String s1="abc"和String s2=new String("abc")的理解
- 关于JAVA中String="abc"和String=new String("abc")的区别与联系
- Java中 "abc" + '/'和"abc" + "/"的区别
- self.abc = nil [abc release]的区别
- new String("abc")与String a="abc"的区别
- self.abc = nil 和 [abc release]的区别
- abc+cba=1333,满足条件的abc有几个
- 从C919模型看ABC三足鼎立
- 从内存角度去分析String s1= "abc"与String s2 = new String("abc")的问题
- 深入java String JVM对String对象的连接优化 一(源码分析)
- 从JVM的角度看JAVA代码1
- 从JVM的角度看JAVA代码--代码优化
- Java的内存机制 String str = "abc" 和String str = new String("abc")的区别
- Java String类型的String s = "abc"和String s = new String("abc")的区别
- a[3] = "abc"
- smallbusiness源碼
- Hello CSDN
- 深入JVM(二):java里的堆(heap)栈(stack)
- Linux系统下安装ISO文件
- MS SQL存储过程分页
- [jvm]深入JVM(一):从"abc"=="abc"看java的连接过程
- 主从处理机内核简介
- CMarkup概述
- Oracle 10g 版本10.2.0.1.0升级到Oracle 10g 10.2.0.3.0过程
- base_堆和栈的区别
- [笔记/简译]WPF的新特性——依赖属性(2)
- Random Taboo Card
- 在Eclipse中使用JAD进行反编译
- 深入分析C++中char * 和char []的区别