当前位置: 首页 > 科技观察

这是Tomcat内存配置的正确姿势

时间:2023-03-19 17:14:31 科技观察

1。背景虽然看了各种大牛的博客或者文章,但是没有找到特别全面的关于JVM内存分配方式的文章。为了严谨起见,其中许多是复制和粘贴的。本文特别说明只介绍基于HotSpotVM虚拟机和JDK1.7的内存分配。关于GC的说法也是基于CMS(不是G1)的并发收集,防止大牛拍砖。目前主流的JVM是HotSpotVM(其次还有J9VM、ZingVM)。目前各种博客文章大部分都是基于JDK1.7以前的版本。(注:由于不同的虚拟机实现,不同的JDK,内存的分布是不同的,也就是说,下面文章中提到的内存结构只是逻辑结构,不是内存的物理结构。)本文仅介绍了内存分配的方法,以及具体的垃圾回收机制。通过这篇文章,让大家对JVM有了一点了解。小编对JVM了解不透,不想误导孩子。2.如果整体内存结构只是为了解决问题,不想知道原因请跳过本章。本文介绍垃圾回收内存区(简称GC堆,不包括程序计数器、栈、本地方法栈)的结构。参考一句大话《一个java对象的这一辈子》我是一个普通的Java对象,我出生在伊甸区,在伊甸区我也看到了和我长得很像的小弟弟(其他Java对象),我们在伊甸区玩过很长时间。有一天Eden区人太多(会触发YoungGC,每次GC会加一年),所以我被迫去了Survivor区的“From”区。自从去了Survivor区,就开始Floating,有时在Survivor的“From”区,有时在Survivor的“To”区,居无定所(每个YoungGC都需要“调换”from区和to区)幸存者区)。直到我18岁(18YoungGCs),爸爸说我长大成人了,是时候闯荡社会了。所以我去了老一代。老一辈的人很多,年纪都挺大的。在这里我也认识了很多人。在老年代,我活了20年,然后被回收(OldGC)。解释一下,首先,内存分为年轻代(young)、老年代(old)、永久代(permanent),如下图年轻代:(对于年轻代的垃圾回收,我们称之为YoungGC简称Younggeneration)年轻代分为eden区,survivor区1.eden区,是newObject(),对象诞生的地方2.survivor区是垃圾回收后还活着的对象存储区,survivor区分为from区和to区2.1.from区:GC回收后,eden区和to区的存活对象会存放在from区2.2.to区:GC回收后,eden区和to区的存活对象eden区和from区将被转移到2.3区。因为2.1和2.2的操作,所以from区和to区的存活对象来回传递,总有一个old区是空的:(针对old区的垃圾回收简称OldGC)18次YoungGC后,年轻代还活着的对象会从年轻代转移到老年代。老年代满后会触发OldGC,存活的对象会继续留在老年代,直到20次OldGC回收***代:(对于年轻代+老年代+***generationcollection(简称FullGC)是HotSpotVM针对Java方法区的一种实现,通常存储类信息、常量池、静态变量、JIT编译代码(简单理解为编译后代码存储)等数据area可以理解为:当我们的java项目运行时,加载的class文件越多,需要的初代内存空间就会越大)(注:据说初代是Hotspotvirtual特有的概念machine,其他JVM都没有这个东西。在Java8中,第一代被完全移除,取而代之的是另一块不连接堆的本地内存——元空间)lang.OutOfMemoryError:Javaheapspace----JVMHeap(堆)溢出原因:项目运行阶段,新建的对象太多,占满了配置的最大内存,就会出现这个错误。解决方法:手动设置Xms,Xmx的大小。常见问题2java.lang.OutOfMemoryError:PermGenspace----PermGenspace(***generation)Overflow原因:当开发的项目中有很多Java文件时,就会出现这个错误(就是项目很large,JVM加载的文件比较多)解决办法:手动设置MaxPermSize大小。常见问题三java.lang.StackOverflowError----StackOverflow原因:通常是某段代码逻辑递归层数过多导致。解决方法:修改递归代码,控制递归层数4.内存分配方式(推荐,非***)本文只介绍一些常用的配置参数。通常第一代不算堆内存(单独占用另一块内存),新生代占老年代的1/2,即整个堆内存的1/3。根据这个原则,我们给出一个配置示例。比如服务器可以提供1G内存供项目使用。根据上图,我们给出如下配置。运行模式:-server服务器模式,当有多个CPU时,性能更好。新生代和老年代:(通常新生代和老年代不单独配置,所以可以直接配置整个内存堆大小)-Xms384m内存堆的初始内存空间-Xmx768m内存堆***内存空间***代:(新生代,老年代配置的剩余内存留给***代使用)---注意jdk1.8去掉了-XX:PermSize=128m***代初始化大小-XX:MaxPermSize=256mGeneration***的内存空间(默认为64m)4.不同环境下的Tomcat内存配置方法对各种内存问题进行了详细的解释,并简要介绍了配置参数。下面我们介绍一下在各种环境下的具体配置方法。1、Tomcat使用命令行启动:修改TOMCAT_HOME/bin/catalina.sh(windows为catalina.bat),在文件-Xms384m-Xmx768m-XX:PermSize=128m-XX上方添加如下语句JAVA_OPTS="-server:MaxPermSize=256m"2.如果tomcat注册为windows服务,使用tomcat目录下的/bin/tomcat8w.exe修改。如图3所示。如果你在使用myeclipse开发的时候,启动tomcat,上面的修改就不起作用了,可以这样设置:Myeclipse->preferences->myeclipse->servers->tomcat->tomcat×.×->JDK面板中可选的JavaVM参数在-server-Xms384m-Xmx768m-XX:PermSize=128m-XX:MaxPermSize=256m***说几句:不管配置是什么,和参数配置的价值在于,需要根据实际项目不断调试,不要轻易放弃。比如tomcat的内存配置不是越大越好,最好是project/server配置