Android 内存 - 运行时数据区

Android程序运行时,产生的变量和状态,都会保存在运行时数据区。所以要理解内存管理,我们要先对运行时数据区有个了解。

运行时数据区分为5个部分:

  • 程序计数器
  • 虚拟机栈
  • 本地方法区
  • 方法区

程序计数器

每个线程都有一个程序计数器,用于记录当前线程所执行的字节码行号,通俗的说,就是记录当前线程执行到了哪里。

Java支持多线程执行程序,由于一个内核同一时间只能执行一条指令,也就是一个内核同一时间只能执行一个线程,所以要不断的切换线程达到多线程工作。所以一个线程被中断前,需要程序计数器记录执行到了哪里。等切回当前线程时,就可以回到记录点,继续执行下去,保证程序能正确执行。

Java规范没有规定该内存区域OOM(OutOfMemoryError)异常。

虚拟机栈

每个线程都有一个虚拟机栈,用于保存执行方法时创建的栈帧。

每个java方法(不包括本地native方法)执行时,都会创建栈帧,用于保存局部变量,操作数栈,出口方法等信息。方法执行时,创建的栈帧会压入虚拟机栈,方法执行完后,创建的栈帧会从虚拟机栈弹出。

简单了解一下栈帧:

局部变量:用于存放方法参数和方法内部定义的局部变量。
操作数栈:记录操作数栈的最大深度,如果在方法内调用其他方法,会保存准备的参数和接收返回结果。
方法返回地址:
(1)正常退出:返回地址和结果(如果有的话)。
(2)异常退出:特别处理,知道就行。

在Java虚拟机规范中,对该区域内存规定了两种异常状况:

  • StackOverFlowError:当线程请求栈深度超出虚拟机栈所允许的深度时抛出。
  • OutOfMemoryError:当Java虚拟机动态扩展到无法申请足够内存时抛出。

本地方法栈

本地方法栈则为虚拟机使用到的本地native方法提供内存空间。有些虚拟机的实现直接把本地方法栈和虚拟机栈合二为一,比如非常典型的Sun HotSpot虚拟机。

和虚拟机栈一样,本地方法栈区域也会抛出StackOverflowError和OutOfMemoryError异常。

Java堆是一块各个线程共享的内存区域,虚拟机启动就被创建,用于储存对象和数组,由垃圾收集器(GC)管理。

Java堆在物理空间上可以是不连续的,只要在逻辑上是连续的即可。可以通过(-Xmx和-Xms)
控制扩展。

在Java虚拟机规范中,对该区域内存规定了一种异常状况:

  • OutOfMemoryError:当Java虚拟机动态扩展到无法申请足够内存时抛出。

方法区

方法区也是一块各个线程共享的内存区域,虚拟机启动就被创建,用于储存已被虚拟机加载的类信息,常量,静态变量等数据。

这个区域存在弱限制度的垃圾回收,而且该区域内存回收的目标主要针对常量池的回收和对类型的卸载。

运行时常量池

运行时常量池是方法区的一部分。Class文件中除了有类的版本、字段、方法、接口等描述等信息外,还有一项信息是常量池(Constant Pool Table),用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。

运行时常量池具有动态性,并非预置入Class文件中常量池的内容才能进入方法区运行时常量池,运行期间也可能将新的常量放入池中,这种特性被开发人员利用得比较多的便是String类的intern()方法。

直接内存

直接内存并不是运行时数据区的一部分。JDK1.4加的NIO中,ByteBuffer有个方法是allocateDirect(int capacity) ,这是一种基于通道(Channel)与缓冲区(Buffer)的 I/O 方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在Java堆和Native堆中来回复制数据。

例子说明

我们new一个对象时,内存是怎么分配的呢:

public class Test {   
    public static void main(String[] args) {        
        public Test t = new Test(); 
    }
}
  • Test类信息会加载到方法区
  • new Test()实例会保存在Java堆
  • 引用t会保存在栈区
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值