深入理解Java虚拟机(周志明)——读书笔记1

第二章:Java内存区域与内存溢出异常

一、运行时数据区域

首先上图,想必大家都很想吐槽,这张图我都要看烂了。
ece93f19d31bdb7ee9bffad947b4d7bf.jpeg

程序计数器

线程私有

它是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能,均需要依赖这个计数器来完成。

虚拟机栈

线程私有

虚拟机栈也就是我们常说的堆栈中的栈。多指局部变量表和TLAB(Thread Local Allocation Buffer:线程私有的分配缓冲区)。

每个方法被执行的时候,Java虚拟机都会同步创建一个栈帧,用于存储局部变量表、操作数栈、动态连接、方法出口等信息。每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在JVM栈中从入栈到出栈的过程。这就意味着虚拟机栈的生命周期与线程相同

本地方法栈

本地Native服务。

Java堆

线程共享

堆得描述为:“ 所有对象的实例以及数组都应当在堆上分配 ”。
因此也会有资料称呼Java堆为GC堆。

方法区

线程共享。

用于存储已被虚拟机加载的类型信息、常量、静态常量、即时编译后的代码缓存等数据。

永久代历史介绍
说到方法区,就不得不说一下永久代。

JDK8以前,许多程序员都喜欢称呼方法区为永久代,其实这两者并不是等价的。《Java虚拟机规范》只是规定了有方法区这么个概念和它的作用,并没有规定如何去实现它。那么,在不同的 JVM 上方法区的实现肯定是不同的了。 同时大多数用的JVM都是Sun公司的HotSpot。在HotSpot上把GC分代收集扩展至方法区,或者说使用永久代来实现方法区。换句话说:方法区是一种规范,永久代是Hotspot针对这一规范的一种实现。

而从现在回顾以前,当年使用永久代来实现方法区并不是一个好主意,这导致了Java应用更容易遇到内存溢出OOM(永久代 -XX:MaxPermSize 的上限,即使不设置也有默认大小。而J9和JRockit只要没有触碰到进程可用内存上限,如32位系统中4GB限制,就不会出问题,因为J9和JRockit不存在永久代这种说法)。例如使用String::intern(); 最后会解释。

当Oracle收购了BEA的JRockit的所有权后,准备把JRockit的优秀的功能,移植到HotSpot中,但由于二者方法区的实现不同,存在诸多的困难,但考虑到HotSpot未来的发展,

HotSpot的开发团队在JDK6的时候,就有计划放弃永久代,逐步改为采用本地内存来实现方法区了。

到了JDK7,已经把原本放在永久代的字符串常量池、静态变量等移出。

而到了JDK8,最终完全废弃了永久代的概念,改用与JRockit、J9一样在本地内存中实现的元空间来代替,把JDK7中永久代剩余的内容,主要是类型信息全部移到元空间中。

回到刚刚说起的 String::intern(); jdk7 版本对 intern 操作和常量池都做了一定的修改。主要包括2点:
(1)将String常量池 从 Perm 区移动到了 Java Heap区。
(2)String::intern() 方法,如果存在堆中的对象,会直接保存对象的引用,而不会重新创建对象。

运行时常量池(方法区一部分)

编译期生成的各种字面量与符号引用。

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

直接内存

并不是虚拟机运行时数据区的一部分,也不是《Java虚拟机规范》中定义的内存区域。这里讲到是因为JDK1.4新加入了NIO,它可以使用Native函数库直接分配堆外内存。

显然,本机的直接内存不会受到Java堆得大小限制,但是,既然是内存,则肯定还是会受到本机总内存(包括物理内存、SWAP分区或者分页文件)大小以及处理器寻址空间的限制,一般服务器管理员配置虚拟机参数的时候,会根据实际内存区设置 -Xmx 等参数信息,但经常忽略直接内存,使得各个区域总和大于物理内存限制(包括物理和操作系统级的限制),从而导致动态扩展是出现OutOfMemoryError异常。

总结:

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值