JVM-随笔
JVM-随笔
常见类加载器:
启动类加载器(bootstrapClassLoader):
扩展类加载器(ExtensionClassLoader):
应用类加载器(AppClassLoader):
双亲委派原则:
1.sun.misc.Launcher :它是一个Java虚拟机的入口应用;
2.某个特定的类加载器在接到类加载的请求时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类
加载任务,就成功返回;只有父类加载器无法完成此加载任务时,才自己去加载;
3.使用双亲委派原则主要是为了保证Java的一种安全机制----沙箱机制(防止恶意代码对Java类库的破坏)
本地接口(native interface):
Java语言本身不能够对操作系统底层进行访问和操作,但是可以通过JNI接口调用其他语言来实现对底层的访问.
本地方法栈(native method stack):它的具体做法是本地方法栈中登记native方法,在Execution Engine执行时加载本地方法库;
PC寄存器:
每个线程都有一个程序计数器,是线程私有的,就是一个指针,指向方法区中的方法字节码(用来存储指向下一条指令的地址,也即将要执行的指令代码),由执行引擎读取下一条指令,是一个非常小的内存空间,几乎可以忽略不计;
虚拟机栈(stack):
虚拟机栈也叫栈内存,主管Java程序的运行,是在线程创建时创建,它的生命周期跟随线程的生命周期,线程结束栈内存也就释放了,
对于栈来说不存在垃圾回收问题,只要线程一结束该栈也就over了,生命周期和线程一致,是线程私有的;基本类型的变量、实例方法、引用类型变量都是在函数的栈内存中分配的;
栈上分配
小对象(一般几十个bytes),在没有逃逸的情况下,可以直接分配在栈上;
直接分配在栈上,可以自动回收,减轻GC压力;
大对象或者逃逸对象无法在栈上分配;
方法区:
-
方法区是跟线程共享的,通常用来保存装载的类的元结构信息,比如:运行时常亮池、静态变量、常量、字段、方法字节码、在类\实例\接口初始化用到的特殊方法等;
-
通常和永久带关联在一起(Java7之前),具体跟jv m的实现和版本有关;
虚拟机堆(heap)
一个JVM实例只存在一个堆内存,堆内存的大小是可以调节的,类加载器读取了类文件之后,需要把类、方法、常变量放到堆内存中,保存所有引用类型的真实信息,以方便执行器执行;
堆在逻辑上分为三个区:新生带,养老带,永久带(Java7之前,Java8移除了永久带,引入了元数据区(metaspace));
新生区又包括,伊甸区(Ed en)、幸存0区(survivor 0 Space)、幸存1区(survivor 1 Space);
堆内存优化
参数:
-Xms 设置初始分配大小,默认为物理内存的1/64;
-Xmx 最大分配内存,默认为物理内存的1/4;
-XX:+PrintGCDetails 输出详细的GC处理日志;
-XX:+HeapDumpOnOutOfMemoryError 发生oom时,输出堆快照信息;
-XX:HeapDumpPath 导出oom的快照信息路径;
-XX:OnOutOfMemoryError 在oom时,执行一个脚本;
-server -Xmx10m -Xms10m -XX:+DoEscapeAnalysis -XX:+PrintGC 表示做了逃逸分析 在栈上分配;
Trace跟踪参数:
-verbose:gc
-XX:+PrintGC 打印GC简要信息;
-XX:+PrintGCDetails 打印GC详细信息;
-XX:+PrintGCTimeStamps 或者 -XX:+PrintGCDateStamps 打印GC发生的时间戳;
-Xloggc:log/gc.log 指定输出GC信息的位置,以文件输出;
-XX:+PrintHeapAtGC 每一次GC后,都打印堆信息;
-XX:+TraceClassLoading 监控类的加载;
-XX:+PrintClassHistogram 按下CRTL + Break 后打印类信息(包括 序号 实例数量 总大小 类型)
堆的分配参数
-Xmn 设置新生代大小
-XX:NewRatio 设置新生代(eden+2*survior)和老年代(不包含永久带(Java7之前))的比值;
4 表示 新生代:老年代=1:4,即新生代占堆内存的1/5;
-XX:SurvivorRatio 设置两个幸存者区(survivor)与eden的比;
8表示两个survivor:eden=2:8,即一个survivor占新生代的1/10;
官方推荐新生代占堆内存的3/8;
幸存代占新生代的1/10;
在发生OOM时记得Dump出堆,确保可以排查现场问题;
永久区分配参数(Java7之前)
-XX:PermSize 设置永久区的初始空间;
-XX:MaxPermSize 设置永久区的最大空间;
他们表示一个系统可以容纳多少个类型;
元数据区(metaspac)(Java8之后)
-XX:MetaSpaceSize 设置元数据区的初始空间;
-XX:MaxMetaSpaceSize 设置元数据区的最大空间;
栈大小分配
-Xss
通常只有几百k
决定了函数调用的深度;
每个线程都拥有独立的栈空间;
局部变量,参数分配在栈上;