jvm的启动:
装载配置 => 加载类 => 执行主方法
由类加载器加载类文件到内存,包括堆,栈,方法区以及本地方法区等等,,,
方法区保存类的信息(常量池,字段方法等信息等等)
堆包含了应用程序中的系统对象
栈是线程私有,由一系列栈帧组成,每一次方法调用都创建一个帧,压栈。栈包括了局部变量,操作数和常量池指针等
线程运行时根据变量或引用(栈)去堆(对象)内查询,根据堆内信息到方法区内查询执行
每个线程由私有的线程工作内存,它和主内存进行交互。
volatile 保证了线程之间变量的可见性
jvm的一些配置参数:
java -jar demo.jar -XX:+printGC 打印一些gc信息
-XX:+PrintGCDetails –打印GC详细信息
-XX:+PrintGCTimeStamps –打印CG发生的时间戳
-Xloggc:~/gc.log –指定GC log的位置,以文件输出
-XX:+TraceClassLoading –监控类的加载
-XX:+PrintClassHistogram 垃圾清理之前打印直方图
-Xmx –Xms 指定最大和最小的堆内存
-XX:OnOutOfMemoryError –在OOM时,执行一些操作
官方推荐新生代占堆的3/8
幸存代占新生代的1/10
-XX:PermSize -XX:MaxPermSize 永久代最开始和最大
-Xss 线程的栈大小
gc的算法种类
(引用计数)引用计数器的实现很简单,对于一个对象A,只要有任何一个对象引用了A,则A的引用计数器就加1,当引用失效时,引用计数器就减1。只要对象A的引用计数器的值为0,则对象A就不可能再被使用
–引用和去引用伴随加法和减法,影响性能
–很难处理循环引用
标记-清除算法是现代垃圾回收算法的思想基础。标记-清除算法将垃圾回收分为两个阶段:标记阶段和清除阶段。一种可行的实现是,在标记阶段,首先通过根节点,标记所有从根节点开始的可达对象。因此,未被标记的对象就是未被引用的垃圾对象。然后,在清除阶段,清除所有未被标记的对象。
标记-压缩算法适合用于存活对象较多的场合,如老年代。它在标记-清除算法的基础上做了一些优化。和标记-清除算法一样,标记-压缩算法也首先需要从根节点开始,对所有可达对象做一次标记。但之后,它并不简单的清理未标记的对象,而是将所有的存活对象压缩到内存的一端。之后,清理边界外所有的空间
将原有的内存空间分为两块,每次只使用其中一块,在垃圾回收时,将正在使用的内存中的存活对象复制到未使用的内存块中,之后,清除正在使用的内存块中的所有对象,交换两个内存的角色,完成垃圾回收(不适用于存活对象较多的场合 如老年代)
串行收集
并行
类加载器流程
加载,连接(验证,准备,解析),初始化
加载:获取二进制流,转换为方法区的数据结构,在堆中生成对应的对象
连接.验证:文件格式,元数据信息,字节码验证等
连接.准备:分配内存,设置初始值,static final直接赋值(常量池)
连接.解析:引用的解析
初始化:静态代码块或者子类构造等
ClassLoader在加载阶段,负责将字节码文件加载到内存中,可定制
BootStrap Extension App Custom
从右向左查询是否已经加载,从左向右加载
锁的颗粒度
nohup java -Dcom.sun.management.jmxremote.port=12345 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=10.16.8.57 -jar xxx.jar &