主要简单总结下面这三个:类加载器(双亲委派机制)、栈(不断放进去、先进后出)、堆(gc调优)
注:只有方法区和堆是线程共享,也只有这两个地方有gc回收,而且主要是堆。
一、类加载器
1、三种类加载器
系统类加载器(用户写的类加载器)
扩展类加载器(系统类加载器的父类加载器)
根加载器:用c或者c++写的,Java获取是null
(扩展类加载器的父类)
2、双亲委派机制
双亲委派机制是为了安全,防止栈是先进后出,下面有底封住,所以main方法先最下面然后a方法,执行完出去,再b方法进来后出去,然后ab相互调用则循环放进去叠加肯定栈溢出!如果方法都正常执行完则main方法也出栈,栈是线程独有,也是线程安全的,只有方法区和堆线程不安全、共享。恶意代码去篡改恶意代码,所以先找到根加载器加载,即rt.jar包这个很大包下,如果不行再去扩展类加载器,即ext目录下,最后才是系统类加载器,比如java.lang.String就是直接加载根加载器。
二、栈
栈存储8大基本类型、对象引用和实例的方法。
栈是先进后出,下面有底封住,所以main方法先最下面然后a方法,执行完出去,再b方法进来后出去,然后ab相互调用则循环放进去叠加肯定栈溢出!如果方法都正常执行完则main方法也出栈,栈是线程独有,也是线程安全的,只有方法区和堆线程不安全、共享。
三、堆
1、三种jvm
怎么看版本?Java version
一般都是sun公司的HotSpot,另外两种是BEA公司和IBM公司的,所以下面的知识都是基于HotSpot。
2、类加载器读取类文件后,一般会把什么放到堆中?
主要是类的实例对象,对应引用存储在栈,如果该引用已经失效则堆里实例就是垃圾,需要回收。
3、堆的三大区域
(新)新生区(伊甸园区、幸存区0区、幸存区1区)
(老)养老区
(长生)永久区
新生区里的gc是轻量级的,只发生在伊甸园区,比如伊甸园区有10个对象了,满了就触发一次轻量级gc,如果经历过这次gc幸存的就放入幸存区0区(from中的也放过来,这样为成为to做准备)此时0区是to,然后1区是空变成to,而0区是from,保证to永远干净(这个就是复制算法,替代引用计数法,后者需要给每个对象发个计数器比较麻烦,而且存在相互引用问题)两个幸存区是过渡区域,如果经过15次(默认,可以自己调)还幸存则触发重量级gc,如果幸存则进入养老区。
真理:经过研究,99%的对象都是临时对象,只用一次,所以能进入养老区的不多(除非while这种)
1.8以后,永久区改成元空间,存储的是Java运行的一些环境和类信息,元空间逻辑上存在,物理上不存在,怎么验证?
默认情况下,jvm使用的最大内存空间是电脑内存的8分之1,而初始最大内存空间是64分之1,怎么代码看出来?调用Runtime类方法。
那如何调大初始化最大内存空间?
在运行设置界面输入:
-Xms1024m -Xms1024m
(前者是初始化内存,64分之1;后者是最大内存,4分之1)
(-Xms后面不能留空,如果要打印各个区情况,并看出元空间物理上不属于堆,则加上
-XX:+PrintGCDetails,在while代码里把上面的1024改成8然后打印可以看到多次gc过程)
(-XX:+HeapDumpOnOutOfMenmoryError
字节除以1024是k,再除以1024是m。
new byte[1024]这是1k
4、oom,内存溢出
while(true)里写个new Random().next(888888)不断拼接字符串,这样就会不断new导致伊甸园区爆掉。
5、oom怎么处理?
首先加大xms和xmx
但线上项目肯定不能这样,还是要排查出哪行代码问题,需要用到JProfiler工具,安装工具的时候不要直接存到c盘,也不要存的有空格的目录,比如默认的program files。
6、复制算法
前面提到的新生代幸存区from和to变换就是复制算法,简单说就是伊甸园区触发一次轻量级gc会把存活对象放入完全干净的to区,当然为了准备作为to区的from区此时也会把自己经历gc后存活对象放入to区,从而保证to区这一半永远干净!
缺点:浪费to区这一半空间,如果存活对象很多这个缺点越明显,因为可能空间不够,但伊甸园区存活对象不多,所以该算法只适合新生代gc回收。
优先:没有内存碎片(连续空间就不算内存碎片)
7、标记清除算法
顾名思义,两步走
A、扫描对象标记存活对象
B、清除没有标记的对象
缺点:两步时间肯定久,而且会有内存碎片,特别是多次以后内存碎片更多
8、标记清除压缩算法
比标记清除算法多一个压缩,即把标记对象放到一起组成连续空间,从而解决标记清除碎片问题,但这样时间更久。
9、最优gc算法
上面三种算法各有千秋,没有最优!
只能根据不同代选择最合适的gc算法,即分代回收算法:
A、新生代:复制算法
B、老年代:标记清除多次+标记清除压缩
jvm学习方法很重要,深入的话就看书或者面试题。
10、JMM
新东西概念最好看百度百科
三部曲
1)什么是JMM?
2)JMM干嘛用?
3)JMM如何学习
JMM即java memory model,Java内存模型
这个是涉及线程的知识,特别是volilate关键字,主要场景就是主内存有个变量a=0,然后每个线程复制到自己内存中可能修改了该值,那如何和主内存变量值保持一致?这样就要用到voliate可见性!
jvm总结(今天请假回来学习)
最新推荐文章于 2022-07-29 23:26:50 发布