【Java】 类内存分析

 

Java虚拟机的内存可分为几个区域:栈stack、堆heap、方法区method area、程序计数器

Java虚拟机栈:

  1. 栈描述的是方法执行的内存模型。每个方法被调用都会创建一个栈帧(存储局部变量、操作数、方法出口等)

  2. JVM为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数、局部变量等)

  3. 栈属于线程私有,不能实现线程间的共享

       4. 栈是由系统自动分配,速度快,栈是一个连续的内存空间

       5. 两种异常:线程请求栈深度大于虚拟机所允许的深度,抛出StackOverflowError

                             如果虚拟机动态扩展时也无法申请到足够内存,抛出 OutOfMemoryError  

Java堆:

  1. 堆用于存储创建好的对象和数组(数组也是对象)

  2. JVM只有一个堆,被所有线程共享

  3. 堆是一个不连续的内存空间,分配灵活,速度慢

方法区:

  1. JVM只有一个方法区,被所有线程共享

  2. 方法区实际也是堆,只是用于存储类、常量相关的信息

       3. 用来存放程序中永远是不变或唯一的内容。(类信息【Class对象】、静态变量、字符串常量等)

程序计数器:

      是一块用于当做当前线程所执行的字节码的行号指示器的内存,通过改变计数器的值来选取下一条需要执行的字节码指令,java 的 jvm多线程是通过线程轮流切换并非配处理器执行时间来实现的,所以每个线程都都有一个独立的程序计数器,此区域没有outofmemoryerror异常情况。

直接内存和NIO类:

       一种基于通道与缓冲区的I/O方式,使用Native函数库直接分配堆外内存,之后通过java堆中DirectByteBuffer对象作为这块内存的 引用来操作,避免Java堆和Native堆中来回复制数据,提高性能。

用一个简单例子 来简单说明:

/**
 * 类内存分析
 * @author 袁盛桐
 */
public class Student {
	String name;
	Computer computer;
	void doSth()
	{
		System.out.println("coding");
	}
	
	public static void main(String[] args) {
		Student  student = new Student();
		student.name = "yst";
		student.doSth();
		
		Computer com = new Computer();
		com.style = "macbook air";
		
		student.computer = com;
	}
	
}

class Computer
{
	String style;
}

新建一个student类 

  1. 在方法区内把类内的代码,静态变量,静态方法和 类内所用的字符串都加载进堆内的方法区
  2. 找到类入口-main方法,在栈中入栈一个main()方法的栈针
  3. 向下继续执行遇到new student()方法后,在栈中入栈一个student()方法栈针
  4. 在堆中开辟一块内存空间表示student类,并把内存块地址赋给new出来的student对象
  5. 把“yst”赋值给student.name
  6. 向下执行,new  computer(),步骤原理类似student类过程
  7. 当栈中栈针执行完成后会自动依次出栈直到所有栈空
  8. 按照 箭头,相互引用,类执行完成

下面是用windows自带画图软件画的示意图,比较粗糙大家见谅~

猜你喜欢

转载自blog.csdn.net/weixin_38516944/article/details/81056490