JAVA内存区域
问题:Java有个东西叫垃圾收集器,它让创建的对象不需要像c/cpp那样delete、free掉,你能不能谈谈,GC是在什么时候,对什么东西,做了什么事情?
虚拟机的自动内存分配机制的帮助下,不再需要为每一个new操作去写配对的delete/free代码,而且不容易出现内存泄露和内存溢出问题。
内存分配管理事托管于JVM的,Java是编译成字节码,由JVM解释执行.
1、JVM虚拟机所管理的内存分为几部分?
两部分:线程共享的(JAVA堆和方法区)、线程私有的(虚拟机栈和本地方法栈、程序计数器)
线程私有:
(1)程序计数器
每个线程都有自己的程序计数器这样当线程执行切换的时候就可以在上次执行的基础上继续执行,程序计数器是每个线程独有的,并非线程共享的,所以是线程安全的
(2)Java虚拟机栈
JAVA方法执行的内存模型:每个方法执行的时候会创建一个栈桢,每一个方法从调用到执行完成,表示一个栈桢在虚拟机栈中的入栈出栈
栈桢可以理解成一个方法的运行空间,主要存储局部变量表和操作数栈
局部变量表:存放编译期可知的基本数据类型,对象引用和returnAdress类型
long和double会占用2个slot(局部变量表的空间单位,局部变量表的内存空间在编译期间就完成分配),其余类型占用一个
两个异常注意:
①线程请求的栈深度大于虚拟机所允许的深度,StackOverflowError
②虚拟机栈扩展无法申请到足够的内存,OutOfMemoryError
(3)本地方法栈
为Native(本地)方法服务,指的就是Java程序调用了非Java代码,算是一种引入其它语言程序的接口
线程共享:
(4)方法区
方法区因为总是存放不会轻易改变的内容,故又被称之为“永久代”
在方法区中,存储了每个类的信息(类的方法,属性)、静态变量、常量以及编译器编译后的代码等。
JVM运行时常量池位于方法区(存放编译期生成的各种字面量和符号引用)
在运行期间也可以将新的变量放入常量池中,而不是一定要在编译时确定的常量才能放入(动态性)。最主要的运用便是String类的intern()方法(检查字符串常量池中是否存在String并返回池里的字符串引用;若池中不存在,则将其加入池中,并返回其引用)
(5)堆
存放对象实例,进行垃圾回收GC