? ? ? ? 学习周志明老师《深入理解Java虚拟机》笔记以及自己的一些理解记录,Java使用虚拟机自动内存管理机制,所以对于Java程序来说不用手动清理内存,但是当内存溢出时,如果我们不了解内存的机制那么排查问题也是相当困难,也不好定位问题本身。
????????Java虚拟机在执行Java程序时,会将它所管理的内存区域分为若干个不同的数据区域,如图所示分为不同的区域,其中黄色为线程独享,紫色为线程共享。
? ? ? ? Java堆(Heap)是虚拟机所管理的内存中最大的一块,并且堆是被所有线程共享的一块内存区域,堆中存放的是对象的实例。GC主要的区域就是堆,所以有时候被称为GC堆。由GC角度看Java堆又可以分为新生代和老年代,如果在细分还可以分成Eden空间、From Survivor空间、To Survivor 空间。
????????
? ? ? ? 注意:当堆内存不足时,系统会抛出OutOfMemoryError的异常,具体异常信息Java heap space,出现该异常可以将 -Xmx 设置为 -Xms 比率1:1或1:1.5。其中-Xms 为JVM启动时候的内存大小,?-Xmx JVM内存最大值。例如我们平时在设置idea的vm参数时会将最大内存设置为2048M?,最小设置为256M就是这两个参数。(可是看下你的idea 下的help栏中的edit custom?vm option中前两个参数就是jvm的内存设置了)
? ? ? ? 方法区(Method Area)线程共享区域,存储被加载的类信息、常量、静态变量、编译后的代码等。虽然Java 虚拟机规范把方法区描述为一个逻辑部分,但是其实他是一个非堆的(Non-Heap),主要目的就是与Java堆作区分。
? ? ? ? 注意:当方法区内存无法完成分配时,也会抛出OutOfMemoryError异常,如果异常信息中包含?PermGen space,即可以确认是方法区报错的可以通过MaxPermSize=512M设置调整,但是最好不要使用因为Java是内存自动管理的尽可能交给Jvm虚拟机,调整xmx让虚拟机自动去分配内存。
? ? ? ? 程序计数器(Program Counter Register)是一块内存比较小的区域,它是程序执行的字节码的型号指示器。工作原理是通过改变计数器的值来选择下一条指令,分之、循环、异常处理、线程恢复等需要该计数器完成
? ? ? ? 注意:此区域是唯一一块 没有OutOfMemoryError的区域,程序计数器只用于Java虚拟机栈,在执行本地方法栈时程序计数器为空。
? ? ? ? Java虚拟机栈(Java Virtual Machine Stacks),也是线程私有的,每个方法在执行方法的时候会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息,线程在执行调用方法时执行入栈,方法返回时执行出栈。线程执行方法时的方法,执行Java方法时使用Java虚拟机栈。
? ? ? ? 注意:局部变量存放的是8中基本类型、对象引用,当分配栈内存不足时,会抛出OutOfMemoeryError异常
? ? ? ? 本地方法栈与Java虚拟机栈类似,也是保存线程执行方法时的信息,只不过本地方法栈执行的是native(原生)方法。
? ? ? ? 注意:本地方法栈会抛出StackOverFlorError和OutOfMemoryError异常,OutOfMemoryError:Unable to create new native thread:调整-Xms -Xmx 两参数减少Heap大小,将内存让给栈,为什么调整-xms和xmx的大小因为堆内存和栈内存加起来的总量对应的都是物理内存是固定的。