JVM2.-创新互联
JVM体系结构创新互联建站-专业网站定制、快速模板网站建设、高性价比儋州网站开发、企业建站全套包干低至880元,成熟完善的模板库,直接使用。一站式儋州网站制作公司更省心,省钱,快速模板网站建设找我们,业务覆盖儋州地区。费用合理售后完善,10余年实体公司更值得信赖。双亲委派机制
分享文章:JVM2.-创新互联
文章URL:http://ybzwz.com/article/coiddo.html
- 类代码加载,并实例化的过程:
- class.car → class loader
- 加载 + 初始化:class loader → class car模版
- new :相当于从class car模版实例化一个对象
- getClass:和new相反。getClassLoader可以获得加载器
- 双亲委派机制:new 一个对象,寻找类的过程:
- 现在boot加载器中寻找(jre/lib/rt.jar)
- 再去ext加载器中寻找(jre/lib/ext/…)
- 最后在app加载器(用户写的)寻找
- 双亲委派的作用:
- 防止用户自己写系统自带的类。例如自己写String是无效的,除非修改rt.jar,但是修改会导致所有的使用String的其他类崩溃
public class Car {public static void main(String[] args) {Car car1 = new Car();
Car car2 = new Car();
System.out.println(car1 == car2); //false,故其hascode不同
System.out.println(car1.getClass() == car2.getClass()); //true,故其hascode相同
System.out.println(car1.getClass().getClassLoader()); //AppClassLoader
System.out.println(car1.getClass().getClassLoader().getParent()); //ExtClassLoader
}
}
SandBox机制- 组成
- 字节校验码:要求用户写的代码符合要求。但是核心类(java/…和javax/…)不需要检验
- 类装载器(其实是双亲委派机制在起作用):不可改变核心类
- 代码:
public class Demo1 {
public static void main(String[] args) {
new Thread(()->{
},"adair");
}
//native:java本身无法完成,无方法体,需要调用底层
//native会进入本地方法栈 → JNI → 本地方法库
//JNI作用,扩展java语言,融合不同编程语言为java使用。
//例如java驱动打印机,管理系统,写外挂
private native void start0();
}
内存
方法区- 方法区是一种规范,实现之前是永久区,如今是元空间。所有定义方法的信息都保存在该区域。
- 静态变量、常量、类信息(构造方法/定义接口)、运行时的常量池都在方法区(static、final、class、 常量池)。但是对象存在于堆中
- main最先执行,最后结束
- 线程结束,栈内存就释放。对于栈不存在垃圾
- 栈内:基本类型 + 对象引用 + 实例方法
- 栈内以栈帧为单位
- 程序正在运行的方法,一定在栈的顶部
JVM有三种
hotspot
、J9VM
、JRockit
、一个JVM只有一个堆,且堆内存的大小可变
堆的东西:类、方法、常量、变量、 真实对象
堆的三个区域:
- 新生区:伊甸园eden、幸存去s0(from)、s1(to)。轻GC
- 养老区:常用的数据。重GC(Full GC)
- 永久区(元空间)
新生区:类的诞生 + 甚至死亡的地方。
eden:对象被new的地方,满了就会触发轻GC,幸存者存放在s1
如果幸存区满了,引发重GC(全局清理),送入养老区
如果养老区满了,则OOM
永久区:常驻内存,存放JDK自身的Class对象。interface元数据,存储的是java运行时的环境。这个区域无GC,关闭JVM即可释放此区域。一个启动类,加载大量第三方jar包,或者生成大量的反射类,直到OOM
- jdk1.6 :永久代,常量池在方法区
- jdk1.7:永久代(退化),常量池在堆中
- jdk1.8:无永久带,常量池在元空间(不再JVM中,本地内存)中
元空间、永久区、方法区、常量池关系:java8 hotspot取消了永久区。方法区是一个规范,规范没变,它就一直在,取而代之的是元空间,元空间存储类的元信息,静态变量和常量池等并入堆中。
元空间:逻辑存在,物理不存在,
JVM调参:
public class Car {public static void main(String[] args) {//jvm试图使用的大内存
long l = Runtime.getRuntime().maxMemory();
//jvm初始化的内存
long l1 = Runtime.getRuntime().totalMemory();
//默认大为电脑内存的1/4,初始化为1/64
System.out.println(l/(double)1024/1024);
System.out.println(l1/(double)1024/1024);
//jvm调参:-Xms1024m -Xmx2g -XX:+PrintGCDetails
}
}
Jprofiler在一个很大项目中,出现了OOM,OOM要想捕获用Error e捕获,如何使用专业工具排错
- Jprofiler作用
- 分析dump文件,定位泄露
- 获得堆的数据
- 安装过程:
- 现在idea中找好Jprofiler接口
- 然后下载Jprofiler,记住安装路径(environment)
- 然后配置接口到jprofiler9/bin/jprofiler.exe
- Vm options配置
-Xms1m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError
- 点击运行代码(死循环),即可生成带有OOM的dump文件,使用jprofiler打开即可分析
- dump文件分析:
- 可以查看大的数据在哪里,很大程度OOM
Thread Dump
可查看线程的main函数中具体第几行出现错误
JVM的GC几乎全部在堆中,对堆的清理大部分在eden区
- 轻GC:在新生区进行操作,操作后会将eden活的对象移到幸存区,从而eden为空。当一个对象经过默认值15次还没死,就去养老区
- Full GC:全局
- GC算法:
- 引用计数法:顾名思义。计数器本身也会有消耗,辣鸡
- 复制算法:s0 s1相互转换,没有内存碎片,但是永远有一半未使用
- 标记清除算法:先进行标记,再清除。两次扫描浪费时间,有内存碎片。
- 标记清除压缩
内存效率:复制算法 >标记清除 >标记压缩 (时间复杂度)
内存整齐度:复制算法 = 标记压缩 >标记清除
内存利用率:标记压缩 = 标记清除 >复制算法
- JVM调优:没有最好的算法,只有最合适的算法 -->分代收集算法
- 年轻代:存活低、故使用复制算法
- 老年代:区域大,存活高。使用标记清楚 + 标记压缩 实现
- JMM就是java memory module,相当于是一个规则
- 作用:
- 缓存一致性协议,用于定义数据读写的规则
- JMM定义了线程和内存之间的抽象关系:线程之间的共享变量存储在主内存(main memory),每个线程都有一个私有的本地内存(local memory),线程的本地内存是从主内存复制的,由于多个线程对一个对象进行操作,因此需要解决volatile
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
分享文章:JVM2.-创新互联
文章URL:http://ybzwz.com/article/coiddo.html