JVM之理解 浅浅的花香味﹌ 2021-09-15 09:14 321阅读 0赞 可以说从刚开始学java之后会有很长时间不会接触到jvm这个东西,直到有一天tomcat出现: **场景一:** ![这里写图片描述][70] **场景二:** ![这里写图片描述][70 1] 然后你为了解决问题,为了理解jvm,就开始打开网页花式搜资料,然后就找到了这里。。。 在jvm之初识([https://blog.csdn.net/tuesdayma/article/details/79600075][https_blog.csdn.net_tuesdayma_article_details_79600075])篇中我们已经提到:jvm中的栈、本地方法栈和程序计数器是线程独享的,而方法区和堆是内存共享的。所以个人觉得,jvm的结构应该定义成这样更为直观: ![这里写图片描述][70 2] **个人理解:** * 前端没发出一次请求,都会从jvm总体内存中分配一个新的栈、本地方法和程序计数器出来,但是方法区和堆是不会重新创建的 * jvm的总体内存=堆内存+方法区+线程数\*(栈内存+本地方法栈内存)(程序计数器内存忽略不记) * Xms、Xmx、Xmn分别表示的是jvm堆内存的起始值、最大值和最小值,并不是jvm总体内存的大小(网上很多文章模棱两可的说是jvm内存。。。);32 位 JVM 最大堆大小 (-Xmx) 被限制为最大 1.5 Gb。64 位 JVM 最大堆大小可为任意大小,但网上说它应小于 28 GB。 * \-Xss表示每个线程的堆栈大小。JDK5.0以后每个线程堆 栈大小为1M,以前每个线程堆栈大小为256K。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一 个进程内的线程数还是有限制的,不能无限生成,大致在3000~5000左右。 **三大OOM:** 在jvm中只有程序计数器是没有设置OOM这个异常的,他是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器,如果线程执行的是java方法,这个计数器记录的就是正在执行的虚拟机字节码指令的地址。如果正在执行的是native方法,这个计数器的值为undefined **1、Java Heap Space:堆内存溢出** java堆用于存储对象实例,我们新创建的对象会出现在堆的新生代的伊甸园区,当我们不断创建对象时,伊甸园区会被塞满,然后就回进入轻度GC,幸存下来的对象将会进入幸存者1区,当幸存者1区塞满之后又会轻度GC,幸存下来的将会进入幸存者2区,幸存者2区塞满之后将会轻度GC出新生到去养老代,当养老代快,满的时候将会深度GC,如果养老代满了就回报异常OOM 一般出现堆内存溢出很有可能就是死循环里面在new对象、数据库中查询结果庞大而没有分页、或者是IO的时候内容较多 **2、Unable to Create new native thread:栈内存溢出** 栈的溢出其实有两种:StackOverflowError、OutOfMemoryError * StackOverflowError: 在刚开始接触java的时候就遇到过,那时候应该是使用了递归调用,进入死循环了。 其实这个错误是由单个栈内存溢出引起的,默认一个线程栈的大小为1M,也就是说在这个线程栈中只要有1M的东西被入栈而没有出栈的话,就会报StackOverflowError这个异常 * OutOfMemoryError:Unable to Create new native thread 这个异常应该是jvm没有足够的内存开辟出一个新的栈内存出来,就会报这个异常;个人觉得这个异常在64位的jdk中是不会发生的,因为网上好像都说64位的jdk,jvm的最大内存取决于操作系统的物理内存,而对于32位的jdk来说,jvm最大貌似只有1.5G到2G之间,也就是说,堆分配1G内存走的话,最多只能创建500个线程,当然可以减少堆内存或者降低Xss来提高能创建的线程数,但是降低Xss容易引起StackOverflowError,减少堆内存容易造成堆内存溢出 **3、PermGen space:方法区溢出** (这个参考网上的) 异常信息:java.lang.OutOfMemoryError:PermGen space 方法区用于存放Class的相关信息,如类名、访问修饰符、常量池、字段描述、方法描述等。 如果要向运行时常量池中添加内容,最简单的做法就是使用String.intern()这个Native方法。该方法的作用是:如果池中已经包含一个等于此String的字符串,则返回代表池中这个字符串的String对象;否则,将此String对象包含的字符串添加到常量池中,并且返回此String对象的引用。由于常量池分配在方法区内,我们可以通过-XX:PermSize和-XX:MaxPermSize限制方法区的大小,从而间接限制其中常量池的容量。 方法区溢出也是一种常见的内存溢出异常,一个类如果要被垃圾收集器回收,判定条件是很苛刻的。在经常动态生成大量Class的应用中,要特别注意这点。 **经典设置:**参考于:[http://pengjiaheng.iteye.com/blog/538582][http_pengjiaheng.iteye.com_blog_538582] \-Xmx3550m:设置JVM最大可用内存为3550M。 \-Xms3550m:设置JVM促使内存为3550m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。 \-Xmn2g:设置年轻代大小为2G。整个堆大小=年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。 \-Xss128k:设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。 \-XX:NewRatio=4:设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。设置为4,则年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5 \-XX:SurvivorRatio=4:设置年轻代中Eden区与Survivor区的大小比值。设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6 \-XX:MaxPermSize=16m:设置持久代大小为16m。 \-XX:MaxTenuringThreshold=0:设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论。 [70]: /images/20210511/11c7089d095c47a7ad82200b2661f2ee.png [70 1]: /images/20210511/14c4ba0f91b04bd0973ac32aadbb2b22.png [https_blog.csdn.net_tuesdayma_article_details_79600075]: https://blog.csdn.net/tuesdayma/article/details/79600075 [70 2]: /images/20210511/c9d935b5a24f4200840b140009b23d20.png [http_pengjiaheng.iteye.com_blog_538582]: http://pengjiaheng.iteye.com/blog/538582
相关 jvm理解 1.堆栈 JVM运行字节码时,所有的操作基本都是围绕两种数据结构,一种是堆栈(本质是栈结构),还有一种是队列,如果JVM执行某条指令时,该指令需要对数据进行操作,那么被操 系统管理员/ 2024年03月26日 19:39/ 0 赞/ 42 阅读
相关 JVM之锁的理解 1. 初识锁 1.1 锁的认知 说起锁给人的第一反应就是各种门上的锁、车锁等等物理存在的可见的实物锁,功能就是为了保护人身财产乃至生命的安全的。今天所 ╰半橙微兮°/ 2022年11月16日 10:53/ 0 赞/ 119 阅读
相关 JVM理解 JVM内存区域 我们在编写程序时,经常会遇到OOM(out of Memory)以及内存泄漏等问题。为了避免出现这些问题,我们首先必须对JVM的内存划分有个具体的认识。J 以你之姓@/ 2022年05月31日 11:29/ 0 赞/ 194 阅读
相关 理解JVM 1.JVM运行时数据区 ![1047932-20190706180121486-835924128.png][] 2.方法区 ![1047932-2019070 拼搏现实的明天。/ 2021年11月02日 14:16/ 0 赞/ 341 阅读
相关 理解JVM之垃圾收集器详解 文章目录 前言 Serial收集器 ParNew收集器 Parallel Scavenge收集器 Se 川长思鸟来/ 2021年09月28日 00:26/ 0 赞/ 274 阅读
相关 JVM理解 1、程序计数器 程序计数器(Program Counter Register)是一块较小的内存空间,它的作用可以看 做是当前线程所执行的字 迷南。/ 2021年09月27日 15:46/ 0 赞/ 330 阅读
相关 JVM之理解 可以说从刚开始学java之后会有很长时间不会接触到jvm这个东西,直到有一天tomcat出现: 场景一: ![这里写图片描述][70] 场景二: ![这里写图片描 浅浅的花香味﹌/ 2021年09月15日 09:14/ 0 赞/ 322 阅读
相关 深入理解jvm之java内存模型 ![5057999-74c3d145ec4d9d7e.png][] java虚拟机栈: 每个方法执行时创建栈帧,存储局部变量表,操作数栈,动态链接,方法出入口等信息。一 小咪咪/ 2021年08月12日 01:58/ 0 赞/ 417 阅读
还没有评论,来说两句吧...