JVM系列之内存区域
每日禅语
有一位年轻和尚,一心求道,多年苦修参禅,但一直没有开悟。有一天,他打听到深山中有一古寺,住持和尚修炼圆通,是得道高僧。于是,年轻和尚打点行装,跋山涉水,千辛万苦来到住持和尚面前,两人打起了机锋。年轻和尚:“请问高僧,您得道之前,做什么?”住持和尚:“砍柴担水做饭。”年轻和尚:“得道之后又做什么?”住持和尚:“砍柴担水做饭。”年轻和尚哂笑:“何谓得道?”住持和尚:“我得道之前,砍柴时惦念着挑水,挑水时惦念着做饭,做饭时又想着砍柴;得道之后,砍柴即砍柴,担水即担水,做饭即做饭,这就是得道。”住持和尚说,得道就是“砍柴即砍柴,担水即担水,做饭即做饭”,这真是一语道破禅机,认认真真地干好手中的每件事情便是得道。不要把佛法想得过于高深和遥不可及,其实佛法很平凡,它存在于我们生活的每个细节之中。做佛就是做人,一个真正成佛的人,往往在人间最平常的地方。正如佛所说,真正的智慧成就,即非般若波罗蜜。“般若波罗蜜”是梵语,是“智慧”的意思,智慧到了极点,到了没有智慧的境界,那才是真智慧。真理就存在于平凡中,能到达人间最平凡处,才能接近佛法之道,也就是做人之道。
在佛家看来,世法与佛法是同样的道理,因此,出家的人要懂世法,世法懂了,佛法就通了。真正的佛法,并不是以梅花明月、洁身自好便能彻悟的,后世学佛的人,只重理悟而不重行持,大错而特错矣。先学做人,再学做佛,这是佛法的本义。一个人如果真的能够照此修行,不但可以使自己获得幸福,还能够造福社会,成为社会的有用之材。
问题1:JVM内存区域和内存模型是一个东西吗?
Java内存区域是指 JVM运行时将数据分区域存储 ,简单的说就是不同的数据放在不同的地方。通常又叫 运行时数据区域。
Java内存模型(JMM)定义了程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节。
问题2:内存区域是一个什么样的东西呢?
JVM的内存区域在JDK1.8之前和JDK1.8以后有一个大的版本更新和不同的点,看看下面两幅图,能不能找到不同点:
JDK1.8之前
JDK1.8之后
问题3:各个模块的代表什么含义呢?
Java 堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。堆是垃圾收集器管理的主要区域,又称为“GC堆”,可以说是Java虚拟机管理的内存中最大的一块。
方法区:方法区(JDK 8 之后改为 Metaspace)存储类的元数据、静态变量和常量池。
栈:栈为每个线程分配,用于存储局部变量表、操作数栈和返回地址。
程序计数器:程序计数器是每个线程独占的,记录线程当前执行的字节码指令地址。
问题4:各个模块的大小怎么计算呢?
堆计算方式:
- 最大堆大小:通过
-Xmx
参数配置,例如:-Xmx2g
表示最大堆大小为 2 GB。- 初始堆大小:通过
-Xms
参数配置,例如:-Xms512m
表示初始堆大小为 512 MB。- 默认值(未指定时):
- 初始大小:物理内存的 1/64(最小 1 MB,最大 1 GB)。
- 最大大小:物理内存的 1/4。
调整方法:
-Xmx
和-Xms
可设置堆的上下限。两者通常设置为相同值以避免堆扩展时的性能开销。
方法区的计算方式:
- 最大 Metaspace 大小:通过
-XX:MaxMetaspaceSize
参数配置,例如:-XX:MaxMetaspaceSize=256m
。- 初始 Metaspace 大小:通过
-XX:MetaspaceSize
参数配置,例如:-XX:MetaspaceSize=128m
。- 默认值(未指定时):
- 初始大小:大约 20 MB。
- 最大大小:受限于物理内存大小。
调整方法:
- 调整
-XX:MetaspaceSize
和-XX:MaxMetaspaceSize
栈的计算方式:
- 线程栈大小:通过
-Xss
参数配置,例如:-Xss1m
表示每个线程的栈大小为 1 MB。- 默认值(未指定时):
- 通常为 1 MB 或 512 KB,具体值依赖于 JVM 实现和操作系统。
调整方法:
- 通过
-Xss
调整。如果线程数过多且栈大小设置过大,可能会耗尽内存。
程序技术器的计算方式:
- 程序计数器占用的内存非常小,JVM 自动分配,无需手动配置。