单位网站建设意义,网站关键词在哪里做,wordpress高端,图片制作软件哪个好用1. 内存结构 线程私有区
程序计算器
作用#xff1a;是一块较小的内存空间#xff0c;存储的是当前线程所执行的字节码文件的序号特点#xff1a;线程私有#xff0c;不会出现内存空间溢出
虚拟机栈
虚拟机栈是管理JAVA方法执行的内存模型#xff0c;每个方法执行时都…1. 内存结构 线程私有区
程序计算器
作用是一块较小的内存空间存储的是当前线程所执行的字节码文件的序号特点线程私有不会出现内存空间溢出
虚拟机栈
虚拟机栈是管理JAVA方法执行的内存模型每个方法执行时都会创建一个当前栈桢在当前栈桢里面存储方法的局部变量表,操作数栈动态链接方法返回值返回地址等信息栈大小决定了方法调用的可达深度递归多少层嵌套调用多少层其他方法在idea中-Xss参数可以设置虚拟机栈的大小
是线程私有的局部变量表存放了编译期可知的所有基本数据类型byte,short,int,long,float,double,boolean,char以及对象引用栈太小或者方法调用过深都将抛出StackOverFlowError异常
本地方法栈
为本地语言服务的栈Native方法服务
线程共享区
堆内存
存放对象实例的区域对象数组以及常量池从java7开始常量池也会使用堆内存
堆内存从GC角度可以分为新生类(Eden区From Survision区和To Survision区)老年代永久代在Java8的时候被移除了
特点是线程贡献需要考虑线程安全问题同时会产生内存溢出问题
-Xms 设置最小堆内存大小不能小于1024K
-Xmx:设置最大堆内存大小不能小于1024K
方法区
用于存储已被虚拟机加载的类信息常量静态变量即时编译器编译后代码等数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oeNxJfex-1677507866501)(null)]
特点
是一块线程共享的内存区域方法区的大小决定了系统可以保存多少个类如果系统定义了太多的类导致方法区溢出虚拟机同样会抛出内存溢出的错误现在说的方法区一般是指元数据区(元空间Metaspacejava8的时候添加的),如果不指定大小默认情况下虚拟机会耗尽系统的可用内存
堆栈的区别
存储的东西不同栈内存存储局部变量和方法调用而堆内存存储对象包括成员变量局部变量还有类变量共享不同栈内存是线程私有的堆内存是所有线程共有的异常错误不同栈空间不足java.lang.StackOverFlowError堆空间不足java.lang.OutOfMemoryError。大小不同栈空间小于堆空间
获取堆内存数据
java.lang.Runtime类中包含了与内存先关的方法
获取剩余空间的的字节数Runtime.freeMemory()
获取总内存的字节数Runtime.totalMenory()
2. 垃圾回收
垃圾回收机制
在Java中程序员不需要显示的去释放一个对象的内存而是由虚拟机自动去执行在JVM中有一个垃圾回收线程他是低优先级的在正常情况下是不会执行的只有在虚拟机空闲或者在堆内存不足时才会触发执行扫描那些被视为垃圾的对象将他们添加到回收的集合中进行回收也可以进行手动回收通过System.gc(),通知GC运行
垃圾回收算法 标记清除法 标记出所有需要回收的对象在标记完成后统一回收的被标记的对象 优点速度比较快 缺点会产生内存碎片碎片过多仍会使得连续空间变少 标记整理 标记出所有需要回收的对象在标记完成后统一进行整理将存活对象进行一端移动减少内存碎片效率相对较低 优点无内存碎片 缺点效率较低 复制算法 开辟两份大小相等的空间一份空间始终空着垃圾回收时将存活对象拷贝进空闲时间 优点:无内存碎片 缺点:占用空间多 分代回收
根据对象的存活周期不同将对象划分为几块比如堆内存的新生代和老年代然后根据各个年代的特点采用最合适的算法进行回收
新生代对象的存活时间比较短因此使用的是复制算法老年代对象存活的时间比较长因此使用的是标记清除或者标记整理
分代垃圾回收的过程
分代垃圾回收器分两个区,新生代和老年代新生代默认占1/3老年代占2/3
新生代使用复制算法新生代里面又分3个区(Eden,To Survivor, From Survicior)默认占比是8:1:1当Eden区满了之后就会触发第一次MinorGC将Eden区和From区存活的对象复制到To Survivor区域然后to Survivor区域和From Survivor互换原来的To Servivor区域成为下一次的From Survivor区域然后清空Eden和From Survivor区中的对象From中的对象每经过一次MinorGC他的年龄值就会加1达到15的移动到老年代这里使用了复制算法老年代满了或者是超过了临界值则会触发完全垃圾回收
判断一个对象是否为垃圾
引用计数法
堆中每个对象实例都有一个引用计数当一个对象被创建的时候且将这个对象实例分配给一个变量该变量计数设置为1当任何其他变量被赋值为这个对象的引用时计数加1但当一个对象实例的某个引用超过了生命周期或者被设置为一个新值时这个对象实例的引用计数将会减1任何引用计数为0的对象都是可以被当做垃圾收集的对象也就是一个垃圾引用计数法容易产生循环引用的问题如果两个对象相互引用那么他们的引用就会一直存在导致一直无法回收为了解决这个问题下面引入了可达性分析法
可达性分析算法
可达性分析算法又叫做根搜索法就是通过一系列的称之为“GC Roots”的对象作为起始点从这些节点开始向下搜索搜索走过的路径被称为Reference Chain影响链当一个对象到GC Roots没有任何链相连时即从 GC Roots节点到该节点是不可达的则这个对象就是可以被当做垃圾收集的对象也就是一个垃圾
可以被作为GC Roots的对象
虚拟机栈中引用的对象方法区静态成员的引用对象方法区常量的引用对象本地方法栈引用的对象
引用类型 强引用 默认声明的就是强引用只要强引用存在垃圾回收器就永远不会回收该对象哪怕内存不足时也不会去回收所以强引用是造成Java内存泄漏的主要原因如果想回收某个对象可以将值赋值为null,切断强引用关系 软引用一些非必需但是仍有用的对象通过SoftReference实现在内存足够的时候软引用对象不会回收在内存不足时则会回收当回收了软引用对象内存还是不足时会抛出内存溢出异常 弱引用比软引用的引用强度更低一些通过WeakReference实现无论内存是否足够JVM都会被进行垃圾回收 虚引用最弱的引用关系通过PhantomReference类实现每次垃圾回收都会被回收主要用于跟踪对象的垃圾回收状态虚引用的对象始终返回一个null,虚引用对象始终和引用队列一起使用当一个对象还存在虚引用时会被加入到引用队列中jvm通过引用队列是否包含这个虚引用来了解这个对象是否将要被进行垃圾回收
3. 对象分配
对象在内存中如何分配
对象优先在Eden区中分配当Eden区没有足够的空间时会触发垃圾回收把存活的对象移动到Survicor空间如果Survivor空间也满了则会把部分对象移动到老年代中如果对象太大是一个大对象则这个对象会直接分配到老年代不会发生GC
对象如何从年轻代进入老年代
对象年龄够老默认是15可以通过XX:MaxTenuringThreshold设置,复制到老年代同时年龄加1大对象会直接分配到老年代大对象的定义和具体的JVM版本堆大小垃圾回收策略有关一般为2K~128k,可以通过XX:pretenureSizeThreshold设置其大小
4. 垃圾收集器
JVM针对新生代和老年代分别提供了不同的垃圾收集器新生代有Serial,ParNew,Parallel Scavenge,针对老年代提供的垃圾收集器有Serial OldParallel OldCMS还有针对不同区域的G1分区收集算法
常见的垃圾收集器
Serial垃圾收集器
Java虚拟机运行在Client模式下的新生代的默认垃圾收集器基于复制算法实现是一个单线程收集器在进行垃圾收集时必须暂停其他所有工作线程直到垃圾收集结束Serial收集器对于但CPU运行环境来说没有线程交互开销可以获得最高的单线程垃圾收集效率
ParNew垃圾收集器
Java虚拟机运行在Server模式下新生代的默认垃圾收集器基于复制算法实现采用多线程模式工作在进行垃圾收集时必须暂停其他所有工作线程直到垃圾收集结束ParNew垃圾收集器默认开启与CPU同等数量的线程进行垃圾回收可以通过-XX:ParallelGCThreads参数调节工作线程数
Parallel Scavenge垃圾收集器
Parallel Scavenge垃圾收集器是为提高新生代垃圾收集效率而设计的垃圾收集器基于复制算法实现采用多线程在系统吞吐量上有很大的优化可以更高效的利用CPU完成垃圾回收任务Parallel Scavenge提供了三个参数用于调节控制垃圾回收的停顿时间及吞吐量分别是控制足最大垃圾收集停顿时间-XX:MaxGCPauseMillis控制吞吐量大小-XX:GCTimeRation控制是否开启自适应调节策略UseAdaptiveSizePolicy
Serial Old垃圾收集器
Serial Old是JVM运行在Client模式下老年代的默认垃圾收集器Serial Old是Serial的老年代实现同Serial一样采用单线程执行不同的是Serial Old基于标记整理算法实现
Parallel Old垃圾收集器
Parallel Old垃圾收集器采用多线程并发进行垃圾回收基于标记整理法实现在设计上优先考虑系统吞吐量其次考虑停顿时间等因素
CMS垃圾收集器
CMS垃圾收集器是为老年代设计的垃圾收集器其主要目的是达到最短时间的垃圾回收停顿时间基于线程的标记清除算法实现
CMS的垃圾回收过程包含4个过程
初始标记只标记GC Roots直接关联的对象速度很快需要暂停所有工作线程并发标记和用户一起工作执行GC Roots跟踪标记过程不需要暂停工作线程重新标记为了确保并发标记的正确性重新标记已经标记的对象需要暂停工作线程并发清除和用户线程一起工作执行清除GC Roots不可达对象的任务不需要暂停工作线程
G1垃圾收集器
G1垃圾收集器是为了避免全区域垃圾收集引起的系统停顿将堆内存划分大小固定的几个独立区域独立使用这些区域跟踪垃圾收集进度同时在维护一个优先级列表根据系统允许的最长垃圾收集时间优先回收垃圾最多的区域相对于CMD垃圾收集器G1垃圾收集器不产生内存碎片可以精确的控制停顿时间在不牺牲吞吐量的前提下实现停顿垃圾回收
G1垃圾回收器的几个重要参数
-XX:MaxGCPauseMillis:暂停毫秒级默认200毫秒-XX:G1HeapRegionSize:区域大小默认最多2048块每块的大小需要为2的幂次方最大为32M-XX:G1NewSizePercent:新生代的最低百分比默认5%-XX:G1MaxNewSizePercent:新生代的最大百分比默认60%
5. 类加载器
类加载器负责将class文件加载到java虚拟机中并为之创建一个Class对象
类加载器的流程
加载:将class文件加载到内存中将静态数据结构转化成方法区中运行时的数据结构在堆中生成一个代表这个类的对象作为数据访问的入口验证确保加载的类符合JVM规范和安全保证被效验类的方法在运行时不会做出危害虚拟机的事件做一个安全检查准备为static变量在方法区中分配内存空间设置变量的初始值注意只设置静态变量不包括实例变量实例变量在对象初始化时赋值解析:虚拟机将常量池内的符号引用替换为直接引用的过程符号引用中的符号可以是任何形式的字面量只要能无歧义的定位到目标即可直接引用是可以直接指向目标的指针相对偏移量或者间接定位到目标的句柄初始化初始化类变量和其他资源使用卸载GCh将对象从内存中卸载
常用的类加载器
启动类加载器(Bootstrap ClassLoader):虚拟机内置类加载器加载java核心类库如JAVA_HOME/jre/lib/rt.jar,resources.jar,sun.boot.class.path使用C/C实现,他没有父类加载器是扩展类加载器和应用程序加载器的父类加载器扩展类加载器(Extension classLoader):由java语言编写从系统属性java.ext.dirs目录中或者JDK安装目录JRE/lib/ext加载类库应用程序类加载器(Application ClassLoader):应用程序类加载器负责加载用户类路径上所指定的类我们程序中默认的类加载器,可以通过ClassLoader#getSystemClassLoader()获取并操作这个加载器
双亲委派机制
双亲委派机制是当一个类加载器需要加载一个字节码文件时首先会把这个任务委托给他的上级类加载器上级类加载器又交给他的上级以此递归直到上级类加载器不能加载该字节码文件然后再自己去加载这个字节码文件如果自己也无法加载则抛出ClassNotFoundException异常这样做的好处是防止一个字节码文件多次加载保证了数据的安全性即使重复加载了也不会是同一个class对象
6. JVM调优
在调优之前要先明确是否需要使用JVM调优因为大多数Java应用是不需要调优的大多数导致GC问题的原因是代码层面的问题比如创建的对象数量过多使用了大量的全局变量和大对象
需要调优的场景
Heap内存(老年代)持续上涨达到设置的最大内存值Full GC次数频繁GC停顿时间过长应用出现OutOfMemory等内存异常系统吞吐量不高
调优步骤
分析GC日志和Demp文件判断是否需要优化确定瓶颈问题点确定JVM调优量化目标调整JVM调优参数包括内存延迟吞吐量观察调优前后的差异不断分析和调整找到最合适的参数将这些参数应用到服务器
调优参数
语法
-XX: ’ 表示启用该选项-XX:- -表示关闭该选项-XX: 给选项设置一个数字类型的值可跟随单位例如:m和M表示兆字节k和K表示k字节g和G表示千兆字节
参数示例
-Xms4g:设置最小堆内存大小为4g,堆内存初始大小
-Xmx4g设置最大堆内存大小为4g,堆内存最大值
-Xmn1200m:设置年轻代大小为1200MB增大年轻代后将会减小老年代的大小这个值对系统性能较大官方推荐配置为整个堆的3/8
-Xss512K:设置每个线程的堆栈大小JDK5.0后每个线程堆栈大小为1MB,以前为256K值越小能创建的线程越多
-XX:NewRatio4:设置年轻代与老年代的比值为1:4年轻代占整个堆栈的1/5
-XX:SurvivorRatio8:设置年轻代中Eden区和Survivor区的比值为2:8一个Survivor区占整个年轻代的1/10
-XX:MaxTenuringThreshold15:设置Survivor区中对象年龄的最大值为15超过这个值则进入老年代如果设置为0则年轻代不经过Survivor直接进入老年代
-XX:UseParNewGC:年轻代
-XX:UseConcMarkSweepGC:老年代常用调优参数
-Xms:初始化堆内存大小默认为物理内存的1/64(小于1G)
-Xmx:堆内存的最大值。默认(MaxHeapFreeRation参数可以调整)空余堆内存大于70%时JVM会减少堆直到-Xms的最小限制
-Xmn:新生代大小包括Eden和两个Survivor区
-XX:MaxDirectMemorySize1G:直接内存报java.lang.OutOfMemoryError:Direct buffer memory异常时可以上调这个值
-XX:DisableExplicitGC:禁止运行期间显示的调用System.gc()来触发full GC
-XX:CMSlnitiatingOccupancyFraction60老年代内存回收阈值默认为68
-XX:ConcGCThreads4:CMS垃圾回收器并行线程数推荐值为CPU核心数
-XX:ParallelGCThreads8:新生代并行收集器的线程数
-XX:MaxTenuringThreshold10:Survivor区的最大年龄值超过就会进入老年代