Java的内存空间学习

由于之前只是上过一门C语言编程课应付考试,以及通过网课了解一些C++语法,程序执行时的具体内存空间分配对于我来说就是一个黑箱。所以在开始学习Java时,我打算了解一下内存空间的基础概念,不求真正理解JVM,只是想能够大概清楚程序的执行是一个怎样的流程。这篇文章只是记录我一些简单的学习体会。

下面是我根据网络资料和一些个人理解绘制的一张简单的示意图,不仅包含内存空间的类型,还有类加载的流程。

Java程序的旅程

在Java的世界里,一切皆对象,所有的方法也都被封装在类的内部,可以说是一门纯粹的OOP语言。我们编写的所有Java代码也都是抽象成一个又一个的类而存在。像我这样的初学者都知道:Java文件经过javac编译成class文件,class文件再交由虚拟机JVM去执行。

然而虚拟机究竟是如何执行class文件的,就是我这篇文章想要分享的。

由上图可以看到,我将运行时的数据空间分成了三块(实际不止,还有本地方法栈和程序计数器),以及额外添加了一个本地磁盘来说明类加载,虚拟机栈是线程私有的,而堆和方法区都是线程共享的。网上关于数据空间的博文有很多,就不一一细说了。

现在假设我们的主程序代码如下:

public class demo{
    public static void main(String args[]){
        Student stu = new Student;
        Student.method();
    }
}

Student类的定义就不写了,只是一个简单的示范而已。主要说一下执行的过程:

  1. JVM将main方法加载进虚拟机栈,开始执行main内部代码
  2. JVM读取到new Student(),于是前往方法区寻找Student相关信息
  3. JVM未查找到Student类信息,从磁盘中加载Student.class文件进入内存

    加载class文件的过程,详见上图中类加载的五步流程图即可

  4. 加载完成后,JVM根据Student的class对象在堆内创建相应的Student对象stu,并将stu的符号引用转换为直接引用(赋予堆内地址)
  5. JVM继续读取到stu.method()(图中误写为Student),根据stu索引到堆内的对象
  6. JVM将对象内方法method加载进栈,开始执行method方法内部代码
  7. method执行完毕后将直接出栈,随后在main中继续向下执行

也就是说,JVM执行时以class文件为基本单位,遵循“需要什么加载什么”的原则。和上一篇关于反射的文章对比阅读,也就对于Java为什么需要反射机制有了更加深刻的理解。

原文地址:https://www.cnblogs.com/acct-zcw/p/12303413.html

时间: 2024-10-10 01:51:08

Java的内存空间学习的相关文章

Java中内存空间的分配及回收

Java中内存分为: 栈:存放简单数据类型变量(值和变量名都存在栈中),存放引用数据类型的变量名以及它所指向的实例的首地址. 堆:存放引用数据类型的实例. Java的垃圾回收: 由一个后台线程GC(Garbage Collection)进行垃圾回收,虚拟机判定内存不够的时候会中断代码的运行,这个时候GC才进行垃圾回收. 缺点:不能够精确的去回收内存. java.lang.System.gc(); 上面代码会建议系统回收内存,但系统不一定回应,会先去看内存是否够用,够用则不予理睬,不够用才会去进行

java分配内存空间

分配内存空间 数组名=new 数据类型[数组长度]: new关键字用来实现为数组或对象分配内存 (堆内存) 数组具有固定的长度.获取数组的长度: 数组名.length 定义数组+分配内存空间 数据类型[]数组名=new 数据类型[数组长度]; 定义数组时不指定长度,分配空间时指定数组长度:如:String cities[] = new String[6]; 数组元素: 数组名[下标值]; 数组下标从0开始  scores[0]=75: 数组的内存分配  栈内存和堆内存 如定义一个数组 int[]

打包apk java 虚拟机内存不足

解决方案:在android->sdk->build-tools-android-version 中有个 dx.bat dx.bat --dex 命令的dx.bat脚本有这样一句代码 REM By default, give dx a max heap size of 1 gig and a stack size of 1meg. rem This can be overridden by using "-JXmx..." and "-JXss..." o

Java虚拟机内存区域

Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间.根据Java虚拟机规范,包括以下几个运行时数据区. 一.程序计数器 内存空间:较小. 作      用:当前线程所执行的字节码的行号指示器. 特性分析:Java虚拟机的多线程的执行是由线程轮流切换并分配处理器执行时间来完成的.在确定的某个时刻,一个处理器只会执行一条线程中的指令.因此,为了线程切换后能恢复到正确的的执行位置,每条线程都需要一个独立的程序计数器,各个线

java运行时内存模式学习

学习java运行时内存模式: 各区介绍: 方法区(线程共享):用于存放被虚拟机加载的类的元数据:静态变量,常量,以及编译和的代码(字节码),也称为永久代(所有该类的实例被回收,或者此类classLoader被回收). Java堆(线程共享):存放对象实例和数组,这里是内存回收的主要地方.可以分为新生代(young)和年老代(tenured).从字面也可以知道,新生代存放刚刚建立的对象 而年老代存放长久没有被垃圾回收机制回收的对象.一般新生代有分为eden,from survivor和to sur

java对象的内存布局(一):计算java对象占用的内存空间以及java object layout工具的使用

最近在学习java对象内存布局方面的一些知识,主要是想知道一个java对象到底占用多少内存空间,以及java对象在内存中到底是什么样子的.c/c++中的sizeof运算符能够方便地告诉我们一个变量占用的内存空间,但是在java中却没有直接提供这种机制.如果想获取java对象占用的内存大小,可以利用java的Instrumentation机制.java.lang.instrument.Instrumentation这个接口提供了getObjectSize(Object objectToSize),

2016021801 - Java内存区域学习笔记

根据<深入理解java虚拟机>学习归纳整理学习笔记 程序计数器 用途:当前线程的字节码文件的行号指示器.(当前机场负责控制飞机降落的空管员:当前线程表示当前机场, 所执行的字节码等同于被等待允许降落的飞机,行号指示器好比下达允许降落指令的空管员) 线程私有(每个机场都有属于自己的空管员,不同机场的空管员相互独立,互不影响) 类比:某个机场(线程)负责控制航班降落(被执行的字节码)的空管员(行号指示器): 每个机场都有属于自己的空管员: 异常:没有.(机场有没有飞机降落,飞机降落过程发生故障,和

java String分配内存空间备忘

栈内存 堆内存 基础类型,对象引用(堆内存地址) 由new创建的对象和数组, 存取速度快 相对于栈内存较慢 数据大小声明周期必须确定 分配的内存由java虚拟机自动垃圾回收器管理.动态分配内存大小 共享特性 栈中如果有字符串,则直接引用 如果没有,开辟新的空间存入值 每new一次在堆内存中生成一个新的对象. 创建之后值可以改变 String类声明后则不可改变 一.栈内存 基础类型int, short, long, byte, float, double, boolean, char和对象引用 栈

java 内存泄露 学习

1.什么事内存泄露 内存泄露就是对象不用了,但是无法回收该对象占用的内存. 2.java不是有垃圾回收机制,咋还会发生内存泄露呢? java的垃圾回收机制就是把无用的对象(GC roots可达与否)用的内存回收,但是垃圾回收不是万能的,在一些场合会出现内存泄露, 长对象持有短对象的引用, 1.静态集合类 1 Static Vector v = new Vector(10); 2 for (int i = 1; i<100; i++) 3 { 4 Object o = new Object();