程序执行过程内存简单分析

我的第一篇博客:Java程序执行过程内存简单分析

Java虚拟机的内存模型图

图片来源于:https://www.cnblogs.com/cjsblog/p/9850300.html
(图片来源于:https://www.cnblogs.com/cjsblog/p/9850300.html)

特点

虚拟机栈: Java虚拟机栈为线程私有,它的生命周期与线程相同(随线程而生,随线程而灭), 如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;当虚拟机栈可以动态扩展,但扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常;Java虚拟机栈描述的是Java方法执行的内存模型:每个方法执行的同时会创建一个栈帧。且Java 虚拟机栈使用的内存不需要保证是连续的。

本地方法栈: 在虚拟机规范中对本地方法栈中方法使用的语言、使用方式与数据结构并没有强制规定,因此具体的虚拟机可以自由实现它。甚至有的虚拟机(比如:Sun HotSpot虚拟机)直接就把本地方法栈和虚拟机栈合二为一。与虚拟机一样,本地方法栈区域也会抛出StackOverflowError和OutOfMemoryError异常。

程序计数器: 程序计数器是一个记录着当前线程所执行的字节码的行号指示器。每个线程工作时都有属于自己的独立计数器

通过一段简单的代码理解程序执行过程中内存的分析

public class Process {
	
	String name;
	int age;
	
	public void show() {
		System.out.println("名称:"+name+"\t年龄:"+age);
	}
	
	public static void main(String[] args) {
		Process p1 = new Process();
		p1.name = "张三";
		p1.age = 20;
		p1.show();
		
		Process p2 = new Process();
		p2.name = "李四";
		p2.age = 23;
		p2.show();
		
	}
}

当程序从main方法开始执行时,在虚拟机栈中就创建了main方法和Process的栈帧,且在执行Process p1 = new Process();时,在堆中创建了Process对象,从方法区中加载类的信息,其中包含了类Process中的各种属性。

	public static void main(String[] args) {
		Process p1 = new Process();

在执行完毕该语句后,Process栈帧出栈。

在这里插入图片描述
接下来执行赋值语句p1.name = "张三"; p1.age = 20; p1.show();值得注意的是,其中 “张三” 字符串并不属于八种基本数据类型,因此在程序开始执行时字符串就会在常量池中加载完,当程序执行到p1.show;时,创建p1.show的栈帧,在执行完后该栈帧出栈。如示意图所示。

在这里插入图片描述
至此p1对象的程序执行完毕,同理可以理解到p2对象的过程,但此时Process类信息已经在p1过程中加载了,因此在执行p2对象的程序过程中无需再次加载。

在这里插入图片描述
程序执行完后清空,程序退出。

方法区是一种规范,可以有不同的实现

规范就是大多数人都认同,且共同遵守的原理或者行为,不在乎内部如何操作;而实现则是个人根据自己需要进行的实际操作和行为。JVM的方法区就是一种规范,规定了它的作用和用途,以及能够存放哪些东西。一个是理论,一个是行为。

在JDK1.7及以前,将java类信息、常量池、静态变量等数据,存储在Perm(永久带)里,永久代和堆相互隔离,永久代的大小在启动JVM时可以设置一个固定值,不可变,类的元数据和静态变量在类加载的时候被分配到永久代里,当常量池回收或者类被卸载的时候,垃圾收集器会回收这一部分内存。

JDK1.7存储在永久代的部分数据就已经转移到Java Heap或者Native memory。但永久代仍存在于JDK 1.7中,并没有完全移除,譬如符号引用(Symbols)转移到了native memory;字符串常量池(interned strings)转移到了Java heap;类的静态变量(class statics variables )转移到了Java heap;即相对于1.7之前的区别就是将字符串常量池移到了堆中。

jdk1.8中把永久代给完全删除了,取而代之的是MetaSpace,运行时常量池和静态变量都存储到了堆中(仍然与堆不相连,但与堆共享物理内存,逻辑上可认为在堆中),MetaSpace存储类的元数据,MetaSpace直接申请在本地内存中(Native memory),这样类的元数据分配只受本地内存大小的限制。

(方法区部分内容参考自https://www.cnblogs.com/duanxz/p/3726574.html)

ps:第一篇博客难免会有瑕疵纰漏,还望不吝赐教,敬请雅正。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值