0
点赞
收藏
分享

微信扫一扫

7、JAVA优化:堆内存分配、垃圾回收器与调整线程池

TOMCAT优化

tomcat优化分为:tomcat自身的优化和Java虚拟机的优化
垃圾都存在heap(堆)中
垃圾确定方法:

跟可达算法、引用计数器标识垃圾

清除垃圾的算法:

标记-清除:     用跟可达法标记出来,然后清除,会造成内存碎片 
标记-压缩:     用跟可达法标记出来,清除,然后整理对象向内存一端移动
复制算法:      先把内存空间分成两半,每次只用其中一半,当这一半用完时,则将存活对象复制到另一半继续使用,最后将之前的一半空间全部清除。内存消耗比较大

效率:复制>标记清除>标记压缩
内存整齐度:复制=标记压缩>标记清除
内存利用率:标记压缩=标记清除>复制

堆内存分代

堆内存分代:年轻代,老年代   
新创建的对象都放在年轻代中,年轻代的对象经过多少次垃圾回收都没被清除,放到老年代

年轻代又分为:Eden园区,幸存区[from(S0),to(S1)]   (幸存区数据挪动指定的次数后,挪动到老年代)

老年代使用的标记-压缩算法,等于full GC,老年代如果满了,如触发全部代的垃圾回收
年轻代使用的复制算法,部分回收

堆内存分配(默认为JVM虚拟机总内存的1/4)

Eden园区站8/30,幸存区占2/30,老年代占2/3
业务生成的对象时间短,就给年轻代分多一点
业务生成的对象时间长,就给老年代分多一点
一般情况下99%的对象都是临时对象

查看JVM内存分配情况

cat Heap.java 
public class Heap {   
    public static void main(String[] args){
        //返回JVM试图使用的最大内存,字节单位
        long max = Runtime.getRuntime().maxMemory();
        //返回JVM初始化总内存
        long total = Runtime.getRuntime().totalMemory();

        System.out.println("max="+max+"字节\t"+(max/(double)1024/1024)+"MB");            
        System.out.println("total="+total+"字节\t"+
(total/(double)1024/1024)+"MB");
    }
}

使用javac编译,生成Heap.class文件
javac Heap.java  

使用java执行
java Heap
max=513802240字节     490.0MB
total=33554432字节    32.0MB

显示详细信息
java -XX:+PrintGCDetails Heap

java 内存调整相关参数

-Xms   初始使用内存大小(年轻代+老年代)
-Xmx   最大使用内存空间,-Xms和-Xmx建议设置成一样,建议分一半,但不要超过32G


-XX:NewSize      年轻代初始化内存大小
-XX:MaxNewSize   年轻代最大使用内存空间,建议和年轻代初始化内存大小设为一样


-Xmnsize   同时设置-XX:NewSize和-XX:MaxNewSize,代替两者
-XX:NewRatio 以比例方式设置新生代和老年代
-XX: SurvivorRatio 以比例方式设置eden和survivor (S0或S1)
-Xss 设置每个线程私有的栈空间大小,依据具体线程 大小和数量

TOMCAT如何调整堆内存大小:

Java可以直接在命令行添加参数
java -Xms1024m -Xmx1024m -XX:+PrintGCDetails Heap

tomcat需要写到配置文件里vim /usr/local/apache-tomcat-9.0.65/bin/catalina.sh
JAVA_OPTS="-Xms1024m -Xmx1024m"
重启tomcat服务
其他的一些服务,优化参数   如halo,可以直接加
java -Xms1024m -Xmx1024m -jar halo.jar

如果内存分配不合理,有可能造成内存满了,导致系统崩溃,出现OOM

造成OOM的情况:
内存分的不够
代码有问题

监控工具:jprofiler,定位oom的问题原因,需要购买

java自带图形化工具可查看堆内存使用情况(中文会乱码,需改成英文)
localectl set-locale LANG=en_US.UTF-8
执行/usr/loacl/jdk/bin/jvisualvm

垃圾回收方式:

并行回收  多个线程
串行回收  一个线程 (不建议用)

垃圾回收器按分代设置不同的垃圾回收器:

如:
年轻代:PS、PN (并行回收)
PS:,关注吞吐量,适用于非交互式程序,集中时间进行垃圾回收
PN:关注交互性,把垃圾时间打碎,回收N次,用户体验好


老年代:CMS和PO
如果年轻代用PS,则老年代用PO配合使用,关注吞吐量
如果年轻代用PN,则老年代用CMS配合使用,关注交互的 


JDK8代:如果是交互式程序,年轻代用PN,老年代用CMS
       如果程序更注重吞吐量,年轻代用PS,老年代用PO
       
JDK11代:G1算法垃圾回收器       

tomcat文件配置catalina.sh设置垃圾回收:
JAVA_OPTS=
"-XX:+UseConcMarkSweepGC -XX: CMSInitiatingOccupancyFraction=80 - XX:+UseCMSCompactAtFullCollection -XX: CMSFullGCsBeforeCompaction=5"

开启JMX功能,打开监听端口,进行远程监控java程序

#为java程序开启JMX很简单,只要在运行java程序的命令后面指定如下命令即可
vim /usr/local/tomcat/bin/catalina.sh
java\
-Dcom.sun.management.jmxremote           \#启用远程监控JMX
-Djava.rmi.server.hostname=10.0.0.100    \#指定自已监听的IP
-Dcom.sun.management.jmxremote.port=12345 \#指定监听的PORT
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-jar app.jar|app.war
使用jconsole可连接

TOMCAT线程池调整

vim /usr/local/tomcat/bin/catalina.sh
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="2000" redirectPort="8443" maxThreads="2000"/>


举报

相关推荐

0 条评论