JVM内存管理[运行时数据区]

文章详细阐述了Java内存的三个主要区域——栈、堆和方法区的交互关系。栈中每个线程有自己的栈帧,用于存储局部变量、操作数栈和动态链接等。堆是线程共享的,用于对象存储和垃圾回收。方法区则存储类信息,包括常量池,其在不同JDK版本中经历了从PermGen到MetaSpace的变化。线程安全问题主要出现在堆中,而内存溢出可能发生在堆或方法区。
摘要由CSDN通过智能技术生成

目录

栈、堆、方法区的交互关系

虚拟机栈

栈帧

动态链接

概述

线程安全问题

垃圾回收

堆内存溢出(OutOfMemoryError.Java heap space)

方法区

理解

组成、内部结构

HotSpot中方法区的变化

为什么永久代要被元空间替代

方法区内存溢出(OutOfMemoryError.PermGen\Metaspace)

.class常量池、运行时常量池、字符串常量池

方法区的垃圾回收


栈、堆、方法区的交互关系

虚拟机栈

每个线程有自己的栈,栈中的数据以栈帧形式存在,一个方法对应一个栈帧

栈帧

局部变量表、操作数栈、动态链接(指向运行时常量池的方法引用)、方法返回地址

动态链接

概述

一个进程对应一个JVM实例,一个JVM实例里只有一个Runtime Data Area(运行时数据区),其中只有一个堆和一个方法区。一个进程可以有多个线程,线程共享堆和方法区,但每个线程都有但单独的程序计数器,本地方法栈和虚拟机栈。

堆可以物理上不连续,但逻辑上是连续的。

线程安全问题

虚拟机栈中的私有变量一般情况下不用考虑线程安全问题,堆的主要部分线程共享的,其中的对象需要考虑线程安全问题。

堆还有一小部分是每个线程独有的——TLAB(thread local allocation buffer)

垃圾回收

堆有垃圾回收(GC)机制,虚拟机栈没有。

堆内存溢出(OutOfMemoryError.Java heap space)

new的对象都存在堆中

new的对象过多,并且没有及时回收,会导致内存溢出

方法区

组成、内部结构

方法区是所有JVM线程共享的区,和堆类似

方法区存和类相关的信息(类型信息、成员、方法、常量等),JDK1.6及之前的方法区包含常量池

HotSpot中方法区的变化

JDK1.6及之前中方法区的实现为PermGen永久代 ,静态变量存放在永久代上。

JDK1.7有永久代,但是字符串常量池和静态变量移到堆中。

JDK1.8及之后的实现为 MetaSpace元空间 ,元空间(包含类型信息、成员、方法、常量等)在本地内存,字符串常量池和静态变量在堆。

为什么永久代要被元空间替代

永久代设置的空间大小不合适或者其中加载的类过多的话,容易产生OOM;元空间在本地内存,最大可分配空间就是系统可用的内存空间。

对永久代进行调优很困难

方法区内存溢出(OutOfMemoryError.PermGen\Metaspace)

大量加载第三方jar包,Tomcat部署的工程过多

.class常量池、运行时常量池、字符串常量池

常量池表是字节码文件(.class文件)的一部分,用于存放编译器生成的各种字面量和符号引用,这部分内容在类加载后存放到方法区的运行时常量池

JDK1.6及之前字符串常量池是常量池中存字符串的那一部分。后来字符串常量池单独跑出来到堆。

方法区的垃圾回收

主要包括:常量池中废弃的常量不再使用的类型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值