目录java
❝对象的建立,内存布局以及访问定位,推导String必问面试题答案程序员
❞
package com.kuaizhan.web.utils;
/** * @author by zengzhiqin * 2020-07-15 */ class Person { String name; public void say(String name) { System.out.println("hello " + name); } } public class TestPerson { public static void main(String[] args){ Person person; person = new Person(); person.say("特朗普"); } } 复制代码
以此为例,结合以前说到的类生命周期来讲(不懂的朋友能够看前面的文章Java类的生命周期,不懂这个都很差意思和别人说我是搞JAVA的 ),当执行到 new Person 的时候:web
分配内存 = 从虚拟机设置的堆内存里面划分一块新对象所需的肯定大小的内存
具体的划分方式根据各家垃圾收集器不一样也采用不一样的划分方式,主要两种:面试
方式一:指针碰撞(假设JAVA堆内存是整整齐齐的,用过的站一块儿,没用过的站一块儿,那么在中间分界地方放个指针,每次新分配往没用过的那边移动一点就行了。这种方式须要垃圾收集器维护这个用过的和没用过的内存,由于运行过程当中可能中间随时有使用过的内存被回收了就出现了缺口,须要垃圾收集器进行整理内存)编辑器
方式二:空闲列表(JAVA堆空闲内存之间是这里缺一块那里缺一块的,虚拟机维护一个空闲内存列表,记录下来哪些空闲哪些占用了,分配的时候从空闲列表里面找)布局
仍是这段代码:flex
package com.kuaizhan.web.utils;
/** * @author by zengzhiqin * 2020-07-15 */ class Person { String name; public void say(String name) { System.out.println("hello " + name); } } public class TestPerson { public static void main(String[] args){ Person person; person = new Person(); person.say("特朗普"); } } 复制代码
调用过程:优化
注意:url
局部变量 person 其实就是一个reference引用,说白了就是一个相似 0x11 的地址,存在于局部变量表里面(局部变量表在栈区,不记得的朋友能够看看上一篇讲JVM内存分布的文章Java跨平台根本缘由,面试必问JVM内存模型白话文详解来了)。spa
引用指向关系: 0x11 => 0x22 => 0x33
reference1 就是局部变量person,指向堆区的实例;而后 new Person() 指向方法区里面的 Person类元数据信息包括sayHello方法。
当调用sayHello的时候,步骤以下三步:
String 面试高频题,其实都是靠推导出来的,记永远是记不清的:
String str = "1" + "2" + "3";
答案:一个对象,编译时候会进行字符串折叠,算是一个优化,之前确实是四个对象,“1”,“2”,“3”,“123” 字符串折叠:若是是常量相加,通俗理解就是先加,而后去常量池找,有直接返回,没有就建立 复制代码
String s1 = "hello";
String s2 = "world"; String s3 = "hello world"; System.out.print(s3 == "hello" + " world") true,根据上面的分析,都是比较常量池的值,是同一个,true System.out.print(s3 == s1 + s2); false,变量相加,只要有一个变量,那么都要先给变量开空间,就成了地址比较 复制代码
String str2 = new String("Trump"); 建立了几个对象?
String str1 = "Trump";
直接去常量池建立一个Trump,栈里面保存引用直接指向常量池”Trump“ String str2 = new String("Trump"); 建立几个对象分状况(String 不可变): 1. 一个对象(若是常量池中已经存在”Trump”,堆里面建立个对象就能够,栈里面来个引用指向堆) 2. 两个对象(若是常量池中不存在”Trump“,先在常量池里面建立”Trump“,而后堆里面new一个对象,最后栈里面来个引用指向堆) System.out.print(str1 == str2); 比较的栈里面的引用地址,指向的东西都不同怎么多是同样的,果断 false System.out.print(str1.equals(str2)); 比较的常量池里面的值,都是Trump, true 复制代码
公众号下篇内容预告:
垃圾回收,JAVA程序员的福音呐
往期推荐:
Java跨平台根本缘由,面试必问JVM内存模型白话文详解来了
从JVM设计者的角度来看.class文件结构,一文弄懂.class文件的身份地位
Java类的生命周期,不懂这个都很差意思和别人说我是搞JAVA的
欢迎批评指正,有收获的朋友点个在看或者分享鼓励一下吧,十分感谢~