上一篇 <<<JVM整体内存结构的图解,直观明了
下一篇 >>>javap命令反查汇编指令汇总
1.类信息存放在方法区(元空间中)
ClassInfoTests a = new ClassInfoTests();
ClassInfoTests b = new ClassInfoTests();
/**
* 两个对象的地址不一致,所以a==b返回false
*/
System.out.println(a==b);
/**
* 由于两个类的class信息都在方法区(元空间),所以下面返回true
*/
System.out.println(a.getClass()==b.getClass());
2.变量信息存放在栈中,对象存储在堆中,intern可以将堆中信息挪到常量池中
/**
* s1和s2都属于临时变量,存储在栈中
* "abc"属于字符串常量,存储在的常量池中
*/
String s1 ="abc";
String s2 = "abc";
/**
* s1==s2 返回true,因为他们比较的是同一块常量池内的地址
*/
System.out.println(s1 == s2);
/**
* s3存储在栈中,new String对象是存储在堆中
* s3==s1 返回false,因为他们的地址不一样
*/
String s3 = new String("abc");
System.out.println(s3 == s1);
/**
* 使用了intern方法后,相当于把堆中的数据移动到常量池中,常量池相当于hashset,有相同的会覆盖
* 所以s3.intern() == s1 返回true
*/
System.out.println(s3.intern() == s1);
3.常量的存放位置
JVM 在运行时使用的全局的 StringTable(就是一个哈希表)。Hotspot 从 Java 7 开始,存放于堆里。
a.字符串常量池放在jvm什么区域
b.字符串的"+"会直接合并,对象的"+"会转为StringBuilder
String s1 = "a";
String s2 = "b";
String s3 = "a" + "b";
String s4 = s1 + s2;
c.非字符串常量直接放在栈的临时变量表中
4.方法执行操作时序图
public void add() {
int a = 1;
int b = 1;
int c = a * b;
}
使用javap –c XXX.class进行汇编后,得到的add方法指令如下:
public void add();
Code:
0: iconst_1
1: istore_1
2: iconst_1
3: istore_2
4: iload_1
5: iload_2
6: imul
7: istore_3
8: return
对象的布局请参考Java基础-对象布局
相关文章链接:
<<<JVM整体内存结构的图解,直观明了
<<<javap命令反查汇编指令汇总
<<<ClassLoader类加载器顺序Demo测试与双亲委派源码解读
<<<自定义SPI和热部署技术破坏类加载器的双亲委派模式
<<<JVM中对象如何完成空间分配和初始化工作
<<<JVM元空间(方法区)和栈内存溢出原因及解决方案
<<<JVM堆内存溢出和内存泄露问题定位和解决
<<<JVM常见死锁问题产生原因和多种诊断方式
<<<服务器CPU飙升为100%问题排查及如何避免
<<<JVM内存诊断命令和排查工具汇总
<<<JVM新生代老年代算法汇总图解
<<<JVM垃圾回收不要手动System.gc的真正原因
<<<JVM垃圾回收引用计数法和根搜索算法图解
<<<JVM垃圾回收STW(Stop-The-World)代码演示
<<<JVM垃圾回收器的发展历程及使用场景汇总
<<<JVM串行并行垃圾回收器的关注点
<<<一张图看懂CMS垃圾回收器的底层原理
<<<G1能作为JDK9默认垃圾回收器的优势分析
<<<CMS和G1的漏标问题解决及三色标记算法图解
<<<GC中新生代进入老年代的方式汇总
<<<GC常用日志参数配置及分析工具说明
<<<FullGC、MinorGC、STW等常见问题如何解答
<<<JVM性能调优的评估指标及调优示例