1.字符串存在哪里?
如下代码,aaa,bbb,ccc内容到底存储在哪里呢:
public class JvmString { public static void main(String[] args) throws InterruptedException { String s1 = "aaa"; String s2 = "bbb"; String s3 = "ccc"; } }
1.1.首先我们需要了解类的结构,jvm是如何工作,到底加载 执行我们写class文件的呢?
请参考: jvm深入分析整理(一) 第一章:JAVA基本结构 ,第二章 堆和方法区(包含常量池)
1.2.查看编译后class文件
看下图:我们知道 JVM会把编译好class文件 部分内容加载到方法区(类名,包名,类修饰符,常量池等等),
这里说道常量池 存储除了包含代码中所定义的各种基本类型(如int、long等等)和对象型(如String及数组)的常量值,所以字符串存放在方法区中。也就是Perm区
1.3 结论
字符串存放在方法区。
2.如果web项目抛出heap oom, 新的请求会遇到什么?
2.1 springmvc写了一个controller,代码如下:
web容器启动jvm参数
import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; /** * <P> * Description: spring mvc的一个http请求 * 测试 jvm OOM后 连接状态 * 1).OutOfMemoryError: PermGen space :(-Xmx20M -Xms20M -Xmn10M -XX:SurvivorRatio=8 -XX:PermSize=10M -XX:MaxPermSize=10M -Xss512k) * 2).java.lang.OutOfMemoryError: Java heap space * java.lang.OutOfMemoryError: GC overhead limit exceeded * (-Xmx100M -Xms100M -Xmn50M -XX:SurvivorRatio=8 -XX:PermSize=50M -XX:MaxPermSize=50M -Xss512k) * </p> * @author xxxxx * @version 1.0 */ @Controller @RequestMapping("web") public class WebController extends BaseController { @RequestMapping(value = "demo.do") public ModelAndView doTest(HttpServletResponse response, HttpServletRequest request, Model model) { logger.info("helloWorld!"); List<String> list = new ArrayList<String>(); String s="testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest"; for(int i=1;i<=1000000000;i++){ list.add(s+i); //为了看测试效果 休息1ms try { TimeUnit.MICROSECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } // return json sendMessage(response, "{\"result\":\"jvm test\"}"); return null; } }
2.2 观察gc情况
先执行 jmap -heap pid查看各个代的大小
C:\Users\******>jmap -heap 4576 Attaching to process ID 4576, please wait... Debugger attached successfully. Server compiler detected. JVM version is 24.51-b03 using thread-local object allocation. Parallel GC with 4 thread(s) Heap Configuration: MinHeapFreeRatio = 40 MaxHeapFreeRatio = 70 MaxHeapSize = 104857600 (100.0MB) NewSize = 52428800 (50.0MB) MaxNewSize = 52428800 (50.0MB) OldSize = 5439488 (5.1875MB) NewRatio = 2 SurvivorRatio = 8 PermSize = 52428800 (50.0MB) MaxPermSize = 52428800 (50.0MB) G1HeapRegionSize = 0 (0.0MB) Heap Usage: PS Young Generation Eden Space: capacity = 41943040 (40.0MB) used = 32742552 (31.225730895996094MB) free = 9200488 (8.774269104003906MB) 78.06432723999023% used From Space: capacity = 5242880 (5.0MB) used = 5215736 (4.974113464355469MB) free = 27144 (0.02588653564453125MB) 99.48226928710938% used To Space: capacity = 5242880 (5.0MB) used = 0 (0.0MB) free = 5242880 (5.0MB) 0.0% used PS Old Generation capacity = 52428800 (50.0MB) used = 28234728 (26.926734924316406MB) free = 24194072 (23.073265075683594MB) 53.85346984863281% used PS Perm Generation capacity = 52428800 (50.0MB) used = 36406824 (34.720252990722656MB) free = 16021976 (15.279747009277344MB) 69.44050598144531% used 16470 interned Strings occupying 2013816 bytes.
访问 controller 5次:http://127.0.0.1:8080/web/demo.do,观察jstat -gcutil pid变化:
这里记录fullgc 前后变化情况:
看下访问页面状态:
工具和jconsole查看情况:
heap,cpu状态观察:
old区状态观察:
2.3.结论
影响gc的原因方方面面,有潜在问题(要长时间观察才能发现)和显示问题(每隔一天两系统可能会故障),这里给大家演示的一个例子(如果程序里存在问题,例如:死循环 可能导致jvm频繁做大量fullGC,在进行fullgc时间内 ,所有服务请求都会处于等待状态, 会导致无法提供正常服务 ),如果系统出现频繁fullgc需要大家关注程序健康,系统优化。
3.java程序中在堆,栈,方法区之间关系
后续补充....
4.JVM相关问题
4.1 为什么HotSpot VM 内存堆的两个Survivor区?
参考讨论主题: HotSpot VM 内存堆的两个Survivor区
下载:sun白皮书
4.2 方法区中的常量池存放的是什么?
5.遇到问题排查方式
后续补充....
6.写项目应当注意哪些方面的性能问题
先简单阐述下,每个公司都会有 前台系统(高并发分布式架构) 和后台系统 (业务系统,业务调度复杂)
前台系统:技术点涵盖面较为广泛,这里仅仅列出其中一部分:
存储或缓存 mysql,hbase,redis,ehcache,bigmemory;
分布式rpc:dubbo,rmi,hessian;
多线程相关:threadpool,juc;
MQ消息队列:rocketmq,redismq,metaQ;
分布式高并发相关技术:bloomfilter,hystrix;
框架:springMVC mybatis hibernate等等
后台系统:设计架构会比前台系统简单些,但业务会比较复杂,更加注重于框架,和rpc使用,以及数据监控保证数据准确无误,其他技术点 例如缓存,消息 多线程相关等作为一般使用。
6.1 学会看jvm工具相关参数
jconsole: 内存(eden/survivor/old/perm/codecache) ,youngGC time;fullGc time开销,如何调优
后续补充....
6.2 mysql连接数影响
1). 数据库连接数的监控
公司可能会对每台服务器 设置连接mysql有个 上线的连接数,如果连接数过大可能会引起一些问题
后续补充....
6.3 使用框架的相关问题
1). hibernate懒加载 慎用(时间开销相对较大),当项目变得很庞大的时候,需要结合 每个请求耗时 结合分析
后续补充....
7.jvm相关oom测试
7.1.heap OOM
import java.util.ArrayList; import java.util.List; /** * heap溢出 * -Xmx10M -Xms10M -XX:PermSize=5M -XX:MaxPermSize=5M * @author ***** * */ public class JvmTest03 { final static int _1M = 1024*1024; public static void main(String[] args) { List<Integer> list = new ArrayList<Integer>(); while(true){ list.add(_1M); } } }
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Arrays.java:2245) at java.util.Arrays.copyOf(Arrays.java:2219) at java.util.ArrayList.grow(ArrayList.java:242) at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:216) at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:208) at java.util.ArrayList.add(ArrayList.java:440) at com.sohu.train.maven_study_01.JvmTest03.main(JvmTest03.java:21)
7.2.perm OOM
import java.util.ArrayList; import java.util.List; /** * 方法区 溢出 permGen * -XX:PermSize=2M -XX:MaxPermSize=2M * @author **** * */ public class JvmTest04 { public static void main(String[] args) { List<String> list = new ArrayList<String>(); int i = 0; while(true){ list.add(String.valueOf(i++).intern()); } } }
Exception in thread "Reference Handler" Error occurred during initialization of VM java.lang.OutOfMemoryError: PermGen space <<no stack trace available>> Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "Reference Handler"
更多参考:
相关推荐
作为一名Java程序员,我们写过很多Java程序。但是,Java程序到底是如何运行的?如何写出更高效的Java代码……?...封亚飞撰写的《揭秘Java虚拟机-JVM设计原理与实现》深入分析了Java虚拟机的运行机制与原理
本书讲述了Java虚拟机一运行 所有Java程序的抽象计算机,还讲了几种与虚拟机密切相关的核心Java API。本书通过分析讲解、可运行的示例、参考资料和applet (它作为文中所述概念的交互式例示),提供了Java技术的深人...
本书摒弃了传统的以解读枯燥的Java虚拟机规范文档和分析繁琐的Java虚拟机源代码的方式来讲解Java虚拟机,取而代之的是,以实践的方式,引导读者如何从零开始构建和实现一个Java虚拟机,整个过程不仅能让读者做到对...
第4节jvm初体验-内存溢出问题的分析与解决 [免费观看] 00:17:59分钟 | 第5节jvm再体验-jvm可视化监控工具 [免费观看] 00:21:17分钟 | 第6节杂谈 [免费观看] 00:12:37分钟 | 第7节Java的发展历史00:27:24分钟 | ...
Java SE 8版-带目录-pdf,本书完整而准确地阐释了Java虚拟机各方面的细节,围绕Java虚拟机整体架构、编译器、class文件格式、加载、链接与初始化、指令集等核心主题对Java虚拟机进行全面而深入的分析,深刻揭示Java...
深入java虚拟机光盘资源jvm-gc-logs-analyzer 这个项目是一个 Java 虚拟机和垃圾收集器日志分析器。 它专用于 JVM 11 及更高版本(JVM 8 支持正在开发中)。 日志必须采用适当的格式和适当的装饰器,检查最后部分的...
第3章详述如何将Java语言编写的程序转换为Java虚拟机指令集,涉及常量、局部变量、控制结构、算术运算、参数接收、方法调用、数组、操作数栈、异常处理、同步与注解等;第4章深入分析用来表示编译后的类和接口的...
对于想了解Java虚拟机的程序员来说,《Java虚拟机规范》是必须阅读的,对于想深入了解Java语言细节的程序员,阅读《Java虚拟机规范》也有极大好处,但是《Java虚拟机规范》、《Java语言规范》发布十余年,一直没有...
本书摒弃了传统的以解读枯燥的Java虚拟机规范文档和分析繁琐的Java虚拟机源代码的方式来讲解Java虚拟机,取而代之的是,以实践的方式,引导读者如何从零开始构建和实现一个Java虚拟机,整个过程不仅能让读者做到对...
/ 112 5.2.5 服务器JVM进程崩溃 / 113 5.3 实战:Eclipse运行速度调优 / 114 5.3.1 调优前的程序运行状态 / 114 5.3.2 升级JDK 1.6的性能变化及兼容问题 / 117 5.3.3 编译时间和类加载时间的优化 / 122 5.3.4 ...
《深入理解Java虚拟机:JVM高级特性与最佳实践》内容简介:作为一位Java程序员,你是否也曾经想深入理解Java虚拟机,但是却被它的复杂和深奥拒之门外?没关系,本书极尽化繁为简之妙,能带领你在轻松中领略Java虚拟机...
2019最新深入理解JVM内存结构及运行原理(JVM调优)高级核心课程视频教程下载。JVM是Java知识体系中的重要部分,对JVM底层的了解是每一位Java程序员深入Java技术领域的重要因素。本课程试图通过简单易懂的方式,系统...
《Java虚拟机规范(Java SE 8版)英文版》全面而准确地阐释了Java虚拟机各方面的细节,围绕Java虚拟机整体架构、编译器、class文件格式、加载、链接与初始化、指令集等核心主题对Java虚拟机进行全面而深入的分析,...
java虚拟机分析与优化PPT(演讲:李镭) 李镭——现任IBM中国有限公司软件部WebSphere高级工程师。 2002年加入IBM公司软件部,至今一直从事中间件产品家族的售前和售后工作。为IBM的重要合作伙伴提供软件的技术支持和...
Java虚拟机的实现)桌面版本的源代码进行分析,得出虚拟机运行的整个流程,并对流程中的关键部分进行深入研 究,同时结合Sun的《Java虚拟机规范》,总结出实现JVM的一些关键步骤,并提出改进JVM运行效率的建议.
, 本书摒弃了传统的以解读枯燥的Java虚拟机规范文档和分析繁琐的Java虚拟机源代码的方式来讲解Java虚拟机,取而代之的是,以实践的方式,引导读者如何从零开始构建和实现一个Java虚拟机,整个过程不仅能让读者做到对...
通过对 Kaffe(一种Java虚拟机的实现 )桌面版本的源代码进行分析 ,得出虚拟机运行的整个流程 ,并对流程中的关键部分进行深入研究 ,同时结合 Sun的《Java虚拟机规范》,总结出实现 JVM的一些关键步骤 ,并提出改进 JVM...
本文通过对JVM的体系结构的深入研究以及一个Java程序执行时虚拟机的运行过程的详细分析,意在剖析清楚Java虚拟机的机理。
本书完整而准确地阐释了Java虚拟机各方面的细节,围绕Java虚拟机整体架构、编译器、class文件格式、加载、链接与初始化、指令集等核心主题对Java虚拟机进行全面而深入的分析,深刻揭示Java虚拟机的工作原理。...