本帖最后由 toShareBeauty 于 2013-7-9 14:53 编辑
{:soso_e179:}高手!能不能更加详细的说一下,字符串池相关的内容,字符串池在那个堆还是栈中,完整的代码是下面的样子:- class StringDemo
- {
- public static void main(String[] args)
- {
- Object s1 = new String("Hello");
- Object s2 = new String("Hello");
-
- if(s1 == s2) {
- System.out.println("s1 and s2 are ==");
- }else if (s1.equals(s2)) {
- System.out.println("s1 and s2 are equals()");
- }
- }
- }
复制代码 这是我模拟 jvm 跑了一下这个程序,有些地方也不太清楚:
当加载 StringDemo 类的时候,"Hello" 是局部变量的常量,它会放在 JVM 的运行时数据区——>方法区——>appClassLoader域——>StringDemo类字节码信息——>常量池 里面么(1.在这个常量池里面,"Hello" 还是以字符串对象的形式存在么,还是引用形式,因为 String 不是 jvm 支持的8种基本数据类型,这个地方 String 是不是还要转为字符,并以字符数组的形式存在于堆内存,让后再用 字符数组 封装成 String 对象, 保存在堆内存中,常量池中保存的只是对个对象的引用)? 当 JVM 执行 StringDemo.main 函数的时候,在 Java 栈 压入 main 函数栈帧,在栈帧——>局部变量区 分配 s1 s2 两个局部变量的空间,并在栈帧的操作栈分配一个引用型存储单元,保存 "Hello" 对象的引用(2.这个引用是执行堆的对象还是只想常量池?),然后让 BootStrap Class Loader 加载 String 类,并动态修改 StringDemo 类在方法区中的常量池里面关于 String 类的符号引用为直接引用(3.这个地方是不是应该在常量池使用 String 对象的时候就做了?),之后调用 String 的构造方法,在 Java 栈 中压入 String 对应的构造函数栈帧,前面指向 "Hello" 的操作栈变量空间,暂时和 String 构造函数栈帧的局部变量共享同一份空间,此时在堆内存中给 String 类分配一个对象,jvm 执行 String 构造函数,完成后返回一个 String 对象的引用(4.这个String 对象的引用保存在哪里是 String 构造函数栈帧的局部变量区还是操作数栈),Java 栈弹出 String 构造函数 栈帧,s1 对应的栈帧的局部变量域中的内存单元指向这个 String 对象。
从这个分析来看有4个对象,一个 char[] ,3 个 String
|