Java内存结构
JVM运行时数据区域
1.线程私有程序计数器
2. 本地方法栈
3. Java虚拟机栈
Java虚拟机栈描述的Java方法的执行模型:
每个方法执行的时候都会创建一个栈帧用于存放局部变量表,操作栈,动态链接,方法出口等信息。一个方法的执行过程,就是这个方法对于栈帧的入栈出栈过程。
属于线程隔离的
线程共享
1. 堆(heap)
堆里存放的时对象的实例
是Java虚拟机管理内存中最大的一块
GC主要工作区域,为高效GC,会把堆细分更多的子区域
线程共享
2. 方法区
存储了每个class的结构信息,包括常量池,字段描述,方法描述
GC的非主要工作区域
内存溢出代码演示
栈溢出
设置启动参数-Xss100k
package com.jvm.memory; /** * 栈溢出 -Xss */ public class StackOutOfMemory { private int length; public int getLength(){ return length; } public void test(){ this.length++; test(); } public static void main(String[] args) { StackOutOfMemory stack = new StackOutOfMemory(); try { stack.test(); } catch (Throwable ex) { System.out.println(stack.getLength()); ex.printStackTrace(); } } }
堆溢出
堆溢出主要是元空间溢出:设置元空间大小-XX:MaxMetaspaceSize=10m
通过cglib动态循环生成类
package com.jvm.memory; import com.jvm.Test3; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; /** * jcmd命令 * * 1.jcmd pid VM.flags:查看jvm的启动参数 * 2.jcmd pid help:列出当前运行的Java进程可以执行的操作 * 3.jcmd pid help JFR.dump:查看具体命令的选项 * 4.jcmd pid PerCounter.print:查看jvm性能相关的参数 * 5.jcmd pid VM.uptime:查看jvm启动时长 * 6.jcmd pid GC.class_histogram:查看系统中类的计数信息 * 7.jcmd pid Threa.print:查看线程堆栈信息 * 8.jcmd pid GC.heap_dump filename:导出heap dump文件,到处文件可以通过jvisualvm查看 * 9.jcmd pid VM.system_properties:查看jvm的属性信息 * 10.jcmd pid VM.sersion:查看目标jvm进程的版本信息 * 11.jcmd pid VM.command_line:查看jvm启动的命令行参数信息 * * jstack:可以查看或道出Java应用程序中线程的堆栈信息 * * jmc:java Mission Control * jfr:java Flight Recorder * */ public class HeapoMemoryVerflow { public static void main(String[] args) { for (;;){ Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(Test3.class); enhancer.setUseCache(false); enhancer.setCallback((MethodInterceptor) (obj, method, args1, proxy) -> proxy.invoke(obj, args1)); System.out.println("haha"); enhancer.create(); } } }