JAVA的内存区域

运行时数据区

  Java虚拟机在执行java程序过程中会将它所管理的内存分为几块不同的区域,方便对对象的管理。每个区域都有对应的管理对象。
在这里插入图片描述

上图就是java运行时内存的模型图。

程序计数器

  程序计数器占用的内存并不多,它就类似于线程执行的中控台,它用来标记线程需要执行的下一行字节码指令,在多线程环境下,每一个线程都有单独的程序计数器,在单核处理器的时候,每一个时刻只会又一个线程执行,那么就会进行线程切换,而每一个线程切换完成后需要回到他正确的执行位置,程序计数器就帮忙干这个事情。
  如果线程执行的java方法,那么它记录的就是虚拟机字节码指定的地址,如果是native方法计数器则为空(undefined),由于每一个线程都有单独的程序计数器,所以它是线程私有的。

Java虚拟机栈

  Java虚拟机栈也是线程私有的,每个方法被执行时都会同步创建一个栈帧用于存储局部变量表,那么在这个方法执行完之后就会出栈。
  虚拟机栈主要存放基本数据类型和引用类型,如果线程请求的深度大于栈的高度就会抛出StackOverflowError异常。栈也是会自动扩容的,当扩容的时候发现申请不到足够的内存了就会抛出OutOfMemoryError。

本地方法栈

  本地方法栈的功能和Java虚拟机栈作用是类似的,只不过Java虚拟机栈是为Java服务的,本地方法栈为本地方法服务(非Java语言,比如c,c++等)。

  关于堆大家可能更加熟悉一点,平时我们new(关键字)创建的对象就在这里,这里也是垃圾收集器主要工作的地方。堆是属于线程共享的。堆中的内存也有着自己的划分,主要划分为新生代,老年代(永久代在jdk8以后被废除,用元空间就行代替)。新生代和老年代针对对象的大小会进入到这两个地方,新生代中被分为Eden区和From Survivor 和To Survivor,Eden区和两个存活区的默认大小是8:1。新创建的对象如果占用内存不是很高就会进入新生代的Eden,而如果创建的对象占用内存很大就会直接进入老年代。为什么这么设计呢,其实和垃圾收集器有关,大家都知道java主流收集器都是采用的分代收集算法,针对新生代和老年代的垃圾收集是不一样,这个后面再细讲,对于新生代的收集效率肯定是比老年代高的,因为新生代普通占用内存少,而且新生代的对象的引用也是少于老年代,为了使尽量压榨垃圾收集器的劳动力就采用了这种收集算法。

方法区

  方法区用于存储类加载的信息,常量,静态变量,即时编译器编译后的代码缓存等。
  这里需要提到一下永久代的概念,很多人会把方法区和永久代混为一谈,jdk8之前,设计者为了方法区能够将堆中的分代收集直接运用到方法区中,这样就不用单独为方法写一个垃圾收集的方法,采用了永久代来实现方法区,但其实后来发现这个策略是极其不好的,更容易发生内存内存溢出,于是虚拟机的开发团队,在jdk6的时候就开始开发替代永久代的方法,在jdk8的时候就完全放弃的永久代这个概念,改用元空间就行代替。

运行时常量池

  这个是方法区的一部分,除了有类的版本,字段,方法,接口等描述信息外,还有一项重要的信息就是常量池表。常量池表的作用是为了存放编译期生成的各种字面量符号的引用,这部分内容在类加载完成后悔放入运行时常量池中。
.1.字面量
在java中,声明为final的int、long、double、char等基本类型的常量值,特殊的字符串文本"abc",abc也是字面量。字面量一出生,其内容、大小全部固定,不会发生改变。
1.符号
符号引用以一组符号来描述所引用的目标,符号引用可以是任何形式的字面量,只要使用时能够无歧义的定位到目标即可。
比如一个类中有着另一个对象的引用,但是由于此时是编译器,并不知道这个对象的实际地址,所以用一个符号来进行代替。

直接内存

  直接内存并不属于运行时数据区,但是使用率也是非常高,他是直接属于操作系统级别的内存不受虚拟机堆大小的控制,也是可能发生OutOfMemoryError(内存溢出) 的,我们使用的NIO类就是使用的直接内存。

元空间

  前面提到了jdk8中永久代被元空间代替了,元空间和直接内存一样都属于本地缓存直接向操作系统申请内存,并不归虚拟机管。只所以用元空间替代,因为永久代是属于堆的,我们无法准确的预计出永久代的大小,而且永久代的对象占用空间都比较大更加容易产生Full GC,而Full GC就意味着会暂停用户线程,影响系统使用。所以基于效率和内存大小就将元空间代替了永久代,而元空间的垃圾收集更加优化,它不会暂停用户线程,而且理论上可申请的容量大小是基于机器的实际物理内存的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值