1.jdk,jre,JVM的关系图
2.参数
-Xmx:最大堆内存,如:-Xmx512m
-Xms:初始时堆内存,如:-Xms256m
-XX:MaxNewSize:最大年轻区内存
-XX:NewSize:初始时年轻区内存.通常为 Xmx 的 1/3 或 1/4。新生代 = Eden + 2 个 Survivor 空间。实际可用空间为 = Eden + 1 个 Survivor,即 90%
-XX:MaxPermSize:最大持久带内存
-XX:PermSize:初始时持久带内存
-XX:+PrintGCDetails。打印 GC 信息
-XX:NewRatio 新生代与老年代的比例,如 –XX:NewRatio=2,则新生代占整个堆空间的1/3,老年代占2/3
-XX:SurvivorRatio 新生代中 Eden 与 Survivor 的比值。默认值为 8。即 Eden 占新生代空间的 8/10,另外两个 Survivor 各占 1/10
3.连接池
当并发量很低的时候,上述伪代码没有任何问题,但当服务单机QPS达到几百、几千的时候,建立连接connect和销毁连接close就会成为瓶颈,此时该如何优化?
举例:
对Oracle数据库进行压力测试,9600并发线程进行数据库操作,
每两次访问数据库的操作之间sleep 550ms,一开始设置的中间件线程池大小为2048
压测跑起来之后是这个样子的
2048连接时的性能数据
每个请求要在连接池队列里等待33ms,获得连接后执行SQL需要77ms
此时数据库的等待事件是这个熊样的:
各种buffer busy waits
数据库CPU在95%左右
接下来,把中间件连接池减到1024(并发什么的都不变),性能数据变成了这样
连接池降到1024后
获取链接等待时长没怎么变,但是执行SQL的耗时减少了
能看到,中间件连接池从2048减半之后,吐吞量没变,但wait事件减少了一半。
接下来,把数据库连接池减到96,并发线程数仍然是9600不变
96个连接时的性能数据
队列平均等待1ms,执行SQL平均耗时2ms
wait事件几乎没了,吞吐量上升。
没有调整任何其他东西,仅仅只是缩小了中间件层的数据库连接池,就把请求响应时间从100ms左右缩短到了3ms。
寻找最合适的连接数值。
连接数 = ((核心数 * 2) + 有效磁盘数)
接池的大小最终与系统特性相关。
比如一个混合了长事务和短事务的系统,通常是任何连接池都难以进行调优的。最好的办法是创建两个连接池,一个服务于长事务,一个服务于短事务。
再例如一个系统执行一个任务队列,只允许一定数量的任务同时执行,此时并发任务数应该去适应连接池连接数,而不是反过来
参考:https://blog.csdn.net/w05980598/article/details/78797310
4.什么是常量池
常量池中包含了代码所定义的各种基本类型(double,float除外)和对象型的常量值
方法区存放了一些常量、静态变量、类信息等,可以理解成class文件在内存中的存放位置。
Java中的常量池,实际上分为两种形态:静态常量池和运行时常量池。
常量池的作用:常量池是为了避免频繁的创建和销毁对象而影响系统性能,其实现了对象的共享。