助你加薪!2021年春招面向编程看这一篇就够了,让你面试无忧! (2)

永久区是一个常驻内存区域,用于存放JDK自身所携带的Class,Interface的元数据,也就是说它存储的是运行环境必须的类信息,被装载进此区域的数据是不会被垃圾回收器回收掉的,关闭JVM才会释放此区域所占用的空间。

public static void main(String[] args){ String s1 = "123456"; String s2 = "123456"; System.out.println(s1==s2)//结果:true-----------第一次定义s1存放在堆中的永久区,所以第二次属于调用 } 方法区

方法区(Method Area),又称永久代,又称非堆区(Non-Heap space)

方法区是被所有线程共享:

所有的字段和方法字节码,以及一些特殊方法如构造函数,接口代码也再此定义。

简单说,所有定义的方法的信息都保存在该区域,此区属于共享区间。

这些区域储存的是:静态变量+常量+类信息(构造方法/接口定义)+运行时常量池。

但是,实例变量存在堆内存中,和方法区无关。

以上,只是逻辑上的定义。在HotSpot中,方法区仅仅只是逻辑上的独立,实际上还是包含在java堆中,也就是说,方法区在物理上属于java堆区中的一部分,而永久区(Permanent Generation)就是方法区的实现。

存放的是

类信息

静态的变量

常量

成员方法

方法区中包含了一个特殊的区域 ( 常量池 )(存储的是使用static修饰的成员)

方法区的实现的演变

jdk1.7之前:hotspot虚拟机对方法区的实现为永久代。

jdk1.8及之后:hotspot移除了永久代用元空间(Metaspace)。

运行时 常量池和 字符串常量池的变化

jdk1.7之前:运行时常量池(包含字符串常量池)存放在方法区,此时hotspot虚拟机对方法区的实现为永久代。

jdk1.7:字符串常量池被方法区拿到了堆中;运行时常量池剩下的东西还在方法区,也就是hotspot中的永久代。

jdk1.8:hotspot移除了永久代,用元空间(Metaspace)取而代之。这时候,字符串常量池还在堆中,运行时常量池还在方法区,只不过方法区的实现从永久代变成元空间(Metaspace)。

代码使用内存情况如下图所示:

助你加薪!2021年春招面向编程看这一篇就够了,让你面试无忧!

上图描述了程序运行时内存的情况,当程序运行完毕,栈内的会清空b2、b1,这样堆内存中的Book对象就没有一个引用指向他,即栈内存中没有指向他的,则满足了GC的清理原则,GC会自动清理掉堆内存中的Book对象。

助你加薪!2021年春招面向编程看这一篇就够了,让你面试无忧!

上图描述了两个对象b1、b2的在栈和堆中内存的使用情况,当b2=b1时,b1指向的地址就覆盖了b2的指向地址,这样原来b2对象在堆中的内存就没东西指向他的地址了,这就满足了GC的自动清理原则。

public static void main(String[] args){ String s1 = "锄禾日当午"; String s2 = "汗滴禾下土"; String s3 = "窗前明月光"; text1 = text1+text2+text3;//先计算text1+text2,产生地址为0x126的对象,接着再计算0x126对象+text3,产生0x127对象 System.out.println(text1);//输出:锄禾日当午汗滴禾下土窗前明月光 }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgwzyj.html