我要学习JVM

本文深入探讨了JVM内存结构,包括堆、方法区、新生代、老年代、元空间等,以及垃圾回收机制,如Minor GC、Major GC和Full GC。讲解了对象晋升老年代的条件、JVM参数设置、内存溢出问题、Jstack工具分析死锁和CPU高占用线程,以及如何解决java.lang.OutOfMemoryError: Metaspace。此外,还提到了字符串常量池、直接内存和逃逸分析等概念。
摘要由CSDN通过智能技术生成

66-
1、堆、方法区 线程共享,一个java进程只有一个堆和一个方法区。
2、在jvm启动时创建堆,空间大小确定;堆内存的大小是可以调节的。
3、-Xms10m 初始堆空间  -Xmx10m最大堆空间
   -X是jvm的运行参数  ms memory start
   -Xms等价于-XX:InitialHeapSize           -Xmx等价于 -XX:MaxHeapSize
   默认初始化堆内存:计算机内存/64;最大堆内存:计算机内存/4
   一旦超过堆区最大内存,会抛出OutOfMemoryError
   通常会将-Xms和-Xmx设置成相同的值,目的:为了能够在java垃圾回收机制清理完堆区后不需要重新分隔计算堆区的大小,从而提高性能;  
4、所有的类对象和数组分配在堆
5、栈-存放局部变量表-存放基本数据类型和引用
6、方法结束后,对象不会马上被移除,只有垃圾回收时会移除
7、GC时会发生stop the world,用户线程停止  优化-堆空间大一点,减少垃圾回收
8、栈只有入栈和出栈,没有垃圾回收;堆和方法区有
9、堆逻辑上划分
   jdk7及之前:新生区、养老区、永久代;
   jdk8及之后;新生区、养老区、元空间
约定:新生区=新生代=年轻代;养老区=老年区=老年代;永久区=永久代
 堆空间大小=新生代+老年代大小
10、查看设置的参数  
jps 查看java进程
jstat -gc 进程id    S0C-总空间  S1C-使用空间  S0U S1U  EC  EU  OC  OU-老年区
RunTime.getRunTime().totalMemory();RunTime.getRunTime().maxMemory()
11、s1和s2只能有一个存放对象,有一个永远是空的
70-
1、Throwable的子类  错误Error-OutOfMemoryError  异常Exception
2、bin/jvisualvm.exe 可视化工具-抽样器-内存-查看占用内存的类
3、配置新生代与老年代的结构占比
默认:-XX:NewRatio=2,标识新生代1,老年代2,新生代占整个堆的1/3
可以修改-XX:NewRatio=4,表示新生代1,老年代4.
一般不会去修改。生命周期比较长的对象偏多,可以把老年代放大一点。
4、在HotSpot中,Eden区和两个Survivor空间,默认比例8:1:1。但是实际是6:1:1
可以修改-XX:SurvivorRatio来调整空间比例。
5、几乎所有的对象都是在Eden区被new出来的,如果对象太大,就直接进入老年代。
绝大部分java对象的销毁都是在新生代进行的。80%
6、-Xmn设置新生代空间的大小(一般不设置)
7、对象分配过程:
新对象申请-Eden区放不下-YGC-Eden区还是放不下-放Old区-Old也放不下-FGC-FGC后还是放不下-OOM
每个存活对象有年龄计数器-年龄=15晋升到老年区
这个临界值可以设置:-XX:MaxTenuringThreshold=15
Eden区满了,触发YGC/Minor GC(此时存活区会被动回收),存活区满了,不会触发
总结:针对幸存者s0、s1区的总结:复制之后有交换,谁空谁是to
      关于垃圾回收:频繁在新生区收集,很少在养老区收集,几乎不在元空间收集。
8、jvm调优:GC少一些
Minor GC=YOUNG GC    、Major GC/Old GC、Full GC
针对HotSpot VM的实现,GC按照回收区域分为两大类型 :部分收集(Partial GC)、整堆收集(Full GC)
部分收集:不是完整收集整个java堆的垃圾收集:
                新生代收集(Yong GC/Minor GC):新生代的垃圾收集(Eden/s0,s1)
                老年代收集(Major GC/Old GC):只是老年代的垃圾收集。  -目前只有CMS GC会有单独收集老年代的行为。
                混合收集(Mixed GC):收集整个新生代以及部分老年代的垃圾收集。  -目前只有 G1 GC
整堆收集: Full GC 收集整个java堆和方法区
9、Minor GC触发机制
当年轻代(Eden 区)空间不足,会触发Minor GC,Survivor满不会触发GC。
因为java对象大多朝生夕灭,所以Minor GC非常频繁,一般回收速度也比较快。
Minor GC会引发STW,暂停其他用户线程,等垃圾回收结束,用户线程才恢复运行。
10、老年代GC触发机制
Major GC速度一般比MinorGC慢10倍以上,一般会先触发以下YGC
11、FullGC触发机制 -5种情况
  调用System.gc()时,系统建议执行Full GC,但不是必然执行
  老年代空间不足
  方法区空间不足
  通过Minor GC后进入老年代的平均大小 大于老年代的可用内存
  由Eden区、s0区向s1区复制时,对象大小大于s1区可用内存,则把该对象转到老年代,且老年代的可用内存小于该对象大小
full gc是开发调优中尽量避免的,这样暂停时间会短一点
12、-Xms10m -Xmx10m -XX:+PrintGCDetails
[GC (Allocation Failure) [PSYoungGen: 2048K->483K(2560K)]                   2048K->958K(9728K), 0.0010579 secs]
YGC日志:                新生代:垃圾回收前大小-》垃圾回收后大小(总大小)  堆空间回收前-》回收后(总)
78-81
1、为社么需要把java堆分代
优化GC性能,GC的时候找没用的对象,不需要对所有区域扫描
2、特殊情况:
如果存活区中相同年龄的所有对象大小总和大于存活区空间的一半,年龄大于等于该年龄的对象,可以直接进入老年代,无需等待阈值年龄
3、堆空间常用参数
-XX:+PrintFlagsInitial:查看所有参数的默认初始值
-XX:+PrintFlagsFinal:查看所有参数的最终值
jinfo -flag SurvivorRatio 进程id   具体查看某一个参数的指令
-XX:+PrintGC  打印GC简要信息
82-86堆结束
1、性能瓶颈-堆空间-降低老年代GC/避开oom
栈空间不存在GC,方法结束会弹出栈,栈由一个个栈帧组成。
堆不是分配对象存储的唯一选择:如果经过逃逸分析后发现:对象并没用逃逸出对象,可能会被优化成栈上分配(非百分百),这样就无需在堆上分配内存,也无需进行垃圾回收。-最常见的堆外存储技术!随着方法执行的结束,栈空间就被移除。
对象的作用域仅在方法中,-未发生逃逸
new的对象可能在方法外被调用-发生逃逸
-XXPrintEscapeAnalysis 查看逃逸分析的筛选结果
开发中能使用局部变量的,就不要在方法外定义。
-XX-DoEscapeAnalysis  关闭逃逸分析   -XX+DoEscapeAnalysis 开启逃逸分析  jdk7及之后默认开启
2、代码优化-同步省略-锁消除
3、代码优化-标量替换
一个无法分解成更小的数据的数据就是标量-比如原始数据类型
那些可以分解成更小的数据叫做聚合量-比如对象
在JIT阶段,通过逃逸分析,发现未逃逸,会把对象分解成若干个其中的成员变量来替换,这个过程就是标量替换。
-XX+EliminateAllocations:开启表里替换,默认开启-将对象打算分配在栈上
4、总结
jdk只有在server模式下,才可以启用逃逸模式-java-version查看,默认是server模式。
87 -开始方法区
1、线程共享-堆、永久代/元空间:方法区具体的实现 - 方法区是堆中的一个逻辑部分,jdk1.7及之前用永久代实现,1.8之后用元空间实现
方法区存储类的结构,比如运行时常量池、属性和方法的数据、方法和构造器的字节码
运行时常量池一直在方法区,字符串常量池由方法区移入堆空间-来自弹幕
《java虚拟机规范》中说:方法区在逻辑上是堆的一部分。但对于HotSpotJVM而言,方法区还有个别名叫Non-Heap(非堆),目的就是和堆分开,所以方法区看作是一块独立于java堆的内存空间。
2、方法区和堆的实际物理内存空间可以不连续
方法区的大小决定了系统可以保存多少个类,如果系统定义了太多的类,导致方法区溢出,虚拟机会抛出内存溢出错误:OutOfMemoryError:MetaSpace/PermGen Space  -堆是Heap Space
3、元空间不在虚拟机设置的内存中,而是使用本地内存。
4、设置方法区内存的大小:
jdk1.7之前 -XX:PermSize设置永久代初始分配空间,默认值20.75M。-XX:MaxPermSize设置永久代最大可分配空间,32位机器默认64M&

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值