java虚拟机---内存区域划分
对于一个笨笨的人来说,学习的最好方法就是不断重复。如果有些东西你看一遍不能理解的话,那就多看几遍。java虚拟机很早就大致看了一遍,但很多地方都不是特别理解,尤其是看到类加载的地方,头皮发麻。不理解jvm的话,很多地方就不能吃透,于是,决定在学习一遍。
再看一遍的时候,想起了前几天面试的时候被问到的问题,说一下java和c/c++的区别,这一点当时答的不好,有一点很明显的区别没有答上。c/c++内存申请、释放不是自动的,需要通过调用malloc()和free/delete申请释放内存,容易造成内存泄漏和内存而溢出。而java的内存的申请和释放由java虚拟机完成。
(一)java虚拟机内存区域划分
1)程序计数器
当前线程执行的字节码的行号指示器(对于java方法,记录的是正在执行的虚拟机字节码指令的地址,native方法,则这个记录为空),字节码解释器通过改变程序计数器的值来选取下一条需要执行的字节码指令
该区域是线程私有区域
该区域是唯一没有内存溢出和内存泄漏的区域
总结一下就是:线程私有,不会出现内存泄漏和溢出的情况,记录的是当前执行虚拟机字节码指令的地址,字节码解释器通过改变它的值来选取下一条执行的字节码
2)java虚拟机栈
java虚拟机栈就是我们常说的栈
描述的是java方法执行的内存模型:每个方法在执行的时候会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息,其中局部变量表是重点关注对象
局部变量表存放了基本数据类型和对象引用(实际对象存储在堆区域)
局部变量表所需的内存空间在编译期间分配完成,在运行过程中,局部变量表在栈帧中内存的大小不会发生变化
该区域存在内存溢出和泄漏的情况,会出现OutOfMemoryError和StackOverflowError异常
3)本地方法栈
和java虚拟机栈差不多,只不过java虚拟机栈为虚拟机执行java方法服务,而本地方法栈则为虚拟机使用到的native方法服务。即服务的方法不一样
也存在内存溢出和泄漏问题,会出现OutOfMemoryError和StackOverflowError异常
4)java堆
所有线程共享的区域,java虚拟机启动时创建。
存放对象实例的地方
是垃圾收集器管理的主要区域
存在内存泄漏和溢出的情况,会出现OutOfMemoryError异常
5)方法区、
线程共享的区域
存储已经被虚拟机加载的类信息、常量、静态变量、即时编译后的代码
存在内存泄漏和溢出的情况,会出现OutOfMemoryError异常
6)运行时常量池
是方法区的一部分
Class文件中的常量池(保存编译期间生成的各种字面量和符号引用),这部分内容将在类加载以后进入方法区的运行时常量池保存
运行时常量池和Class文件常量池的区别:运行时常量池具有动态性,运行期间也可以将新的常量放入池中
存在内存泄漏和溢出的情况,会出现OutOfMemoryError异常