官方文档
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html
一些重要概念的验证。jvm的参数太多了
OOM
-XX:MaxDirectMemorySize
/**
* VM Args:-XX:MaxDirectMemorySize=100m
* 堆外内存(直接内存溢出)
*/
public class DirectOom {
public static void main(String[] args) {
//直接分配128M的直接内存(100M)
ByteBuffer bb = ByteBuffer.allocateDirect(128*1024*1204);
}
}
-Xms30m -Xmx30m -XX:+PrintGCDetails (打印信息)
/**
* VM Args:-Xms30m -Xmx30m -XX:+PrintGCDetails
* 堆内存溢出(直接溢出)
*/
public class HeapOom {
public static void main(String[] args)
{
String[] strings = new String[35*1000*1000]; //35m的数组(堆)
}
}
-XX:+HeapDumpOnOutOfMemoryErro (GC调优---生产服务器推荐开启(默认是关闭的))
/**
* VM Args:-Xms30m -Xmx30m -XX:+PrintGC 堆的大小30M
* 造成一个堆内存溢出(分析下JVM的分代收集)
* GC调优---生产服务器推荐开启(默认是关闭的)
* -XX:+HeapDumpOnOutOfMemoryErro
*/
public class HeapOom2 {
public static void main(String[] args)
{
//GC ROOTS
List<Object> list = new LinkedList<>(); // list 当前虚拟机栈(局部变量表)中引用的对象 是1,不是走2
int i =0;
while(true){
i++;
if(i%10000==0) System.out.println("i="+i);
list.add(new Object());
}
}
}
导入cglib-3.2.5.jar,asm-5.0.4.jar 我一般直接用gradle管理比较方便
-XX:MetaspaceSize=10M -XX:MaxMetaspaceSize=10M
/**
* cglib动态生成
* Enhancer中 setSuperClass和setCallback, 设置好了SuperClass后, 可以使用create制作代理对象了
* 限制方法区的大小导致的内存溢出
* VM Args: -XX:MetaspaceSize=10M -XX:MaxMetaspaceSize=10M
* */
public class MethodAreaOutOfMemory {
public static void main(String[] args) {
while (true) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(MethodAreaOutOfMemory.TestObject.class);
enhancer.setUseCache(false);
enhancer.setCallback(new MethodInterceptor() {
public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
return arg3.invokeSuper(arg0, arg2);
}
});
enhancer.create();
}
}
public static class TestObject {
private double a = 34.53;
private Integer b = 9999999;
}
}
堆栈溢出 -Xss1m
/**
* 栈溢出 -Xss1m
*/
public class StackOverFlow {
public void king(){//一个栈帧--虚拟机栈运行
king();//无穷的递归
}
public static void main(String[] args)throws Throwable {
StackOverFlow javaStack = new StackOverFlow(); //new一个对象
javaStack.king();
}
}
JVM 运行底层基础逻辑 , 结合HSDB去查看
Object回收的JMM
/**
*从底层深入理解运行时数据区
* -Xms30m -Xmx30m -XX:+UseConcMarkSweepGC -XX:-UseCompressedOops
* -Xss1m
*/
public class JVMObject {
public final static String MAN_TYPE = "man"; // 常量
public static String WOMAN_TYPE = "woman"; // 静态变量
public static void main(String[] args)throws Exception {//栈帧
Teacher T1 = new Teacher();//堆中 T1 是局部变量
T1.setName("Mark");
T1.setSexType(MAN_TYPE);
T1.setAge(36);
for (int i=0;i<15;i++){//进行15次垃圾回收
System.gc();//垃圾回收
}
Teacher T2 = new Teacher();
T2.setName("King");
T2.setSexType(MAN_TYPE);
T2.setAge(18);
Thread.sleep(Integer.MAX_VALUE);//线程休眠很久很久
}
}
class Teacher{
String name;
String sexType;
int age;//堆
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSexType() {
return sexType;
}
public void setSexType(String sexType) {
this.sexType = sexType;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
栈帧之间数据的共享
/**
* 栈帧之间数据的共享
*/
public class JVMStack {
public int work(int x) throws Exception{
int z =(x+5)*10;//局部变量表有
Thread.sleep(Integer.MAX_VALUE);
return z;
}
public static void main(String[] args)throws Exception {
JVMStack jvmStack = new JVMStack();
jvmStack.work(10);//10 放入main栈帧操作数栈
}
}
虚拟机优化手段-方法内联
实际上就是减少方法,原理就是减少方法进出虚拟机栈的消耗
/**
* 方法内联
*/
public class MethodDeal {
public static void main(String[] args) {
// max(1,2);//调用max方法: 虚拟机栈 --入栈(max 栈帧)
boolean i1 = 1>2;
}
public static boolean max(int a,int b){//方法的执行入栈帧。
return a>b;
}
}
打断点查看,或者javap -c 查看字节码
/**
* 栈帧执行对内存区域的影响
*/
public class Person {
public int work()throws Exception{//运行过程中 打包一个栈帧
int x =1;//x是一个局部变量
int y =2;
int z =(x+y)*10;
return z;
}
public static void main(String[] args) throws Exception{
Person person = new Person();//person 一个引用, new Person()对象
person.work();//执行完了,出栈
person.hashCode();
int i =12;
}
}
既然都看到了最后,那么送你一份礼物:一个排序算法非常好的图解文章
https://xiaozhuanlan.com/
再次可以搜索关注公众号:
靖驿站
或者
IT-TIANYA
网友评论