1.简介
以上个区域只是表示内存模型,并不代表各个区域的大小或者所占比例
2.程序计数器
3.Java 虚拟机栈
StackOverFlowError(栈溢出)
(一般递归调用方法时,如果没有截止条件,就会一直向虚拟栈中压入方法的栈帧,直到超过虚拟栈的内存,就会抛出该异常)
OutOfMemoryError(内存溢出)
这种异常在单线程运行环境中应该是不会出现的,因为一般会先抛出StackOverFlowError,多线程的话,因为总的进程的大小是固定的,所以,如果线程比较多,占用的内存就比较大,栈深度还没达到StackOverFlowError,内存已经不够了,申请不到内存就抛出了OutOfmemoryError
4.本地方法栈
虚拟机栈是为虚拟机执行java方法服务的,
本地方法栈是为虚拟机执行native方法服务的.
HotSpot 虚拟机中本地方法栈与虚拟机栈合并在了一起,占同一块内存
5.Java堆
作用: 存储对象实例(所有的实例都存放在堆中)
又分为新生代,老年代等,这样划分主要是为了垃圾回收,具体在垃圾回收机制中了解.
6.方法区
垃圾回收很少会出现在这一部分,但是也会有(以后再说),这里主要是了解方法去的作用,主要就是加载类信息,常量,静态变量等...
7.运行时常量池
是方法区的一块,用于存放编译期生成的各种字面量(可以理解为字符串的值),和符号,
总之:直接通过s1与s2这种形式声明的字符串是放在运行时常量池中的StringTable(类似hashset结构)中的,在s1声明之后,运行时常量池已经有了字面量为abc 了,这时,再声明s2时,只是将abc的引用赋值给了s2,其实就是s1的值,所以两者是相等的.
通过new 得到的字符串s3则走的是不同对象实例的创建过程,该实例存储在堆中,所以其引用肯定是与s1不同的,所以两者不相等.