1.这究竟是码困为什么呢?都说JVM能实际使用的内存比-Xmx指定的少,头大
2.java面试时问在项目开发时遇到最难的是什么问题,怎么解决
3.Java为什么可以在多个平台上运行
这究竟是为什么呢?都说JVM能实际使用的内存比-Xmx指定的少,头大
这确实是个挺奇怪的问题,特别是码困当最常出现的几种解释理由都被排除后,看来JVM并没有耍一些明显的码困小花招:
要弄清楚这个问题的第一步就是要明白这些工具的实现原理。通过标准APIs,码困我们可以用以下简单语句得到可使用的内存信息。
而且确实,码困现有检测工具底层也是码困流媒体中文源码用这个语句来进行检测。要解决这个问题,码困首先我们需要一个可重复使用的码困测试用例。因此,码困我写了下面这段代码:
这段代码通过将new int[1__]置于一个循环中来不断分配内存给程序,码困然后监测JVM运行期的码困当前可用内存。当程序监测到可用内存大小发生变化时,码困通过打印出Runtime.getRuntime().maxMemory()返回值来得到当前可用内存尺寸,码困输出类似下面语句:
实际情况也确实如预估的码困那样,尽管我已经给JVM预先指定分配了2G对内存,码困指标源码安装图在不知道为什么在运行期有M内存不见了。你大可以把 Runtime.getRuntime().maxMemory()的返回值2,,K 除以来转换成MB,那样你将得到1,M,正好和M差M。
在成功重现了这个问题之后,我尝试用使用不同的GC算法,果然检测结果也不尽相同。
除了G1算法刚好完整使用了我预指定分配的2G之外,其余每种GC算法似乎都不同程度地丢失了一些内存。
现在我们就该看看在JVM的源代码中有没有关于这个问题的解释了。我在CollectedHeap这个类的源代码中找到了如下的解释:
我不得不说这个答案藏得有点深,但是只要你有足够的好奇心,还是不难发现的:有时候,有一块Survivor区是充电宝app源码不被计算到可用内存中的。
明白这一点之后问题就好解决了。打开并查看GC logging 信息之后我们发现,在Serial,Parallel以及CMS算法回收过程中丢失的那些内存,尺寸刚好等于JVM从2G堆内存中划分给Survivor区内存的尺寸。例如,在上面的ParallelGC算法运行时,GC logging信息如下:
由上面的信息可以看出,Eden区被分配了,K,两个Survivor区都被分配到了,K,老年代(Old space)则被分配了1,,K。把Eden区、老年代以及一个Survivor区的尺寸求和,刚好等于2,音乐vip源码搭建,K,说明丢失的那M(,K)确实就是剩下的那个Survivor区。
总结而言,当JVM在运行时报告的可使用内存小于-Xmx指定的内存时,差值通常对应于一块Survivor区的大小。对于不同的GC算法,这个差值可能有所不同。
java面试时问在项目开发时遇到最难的是什么问题,怎么解决
面试时,回答在项目开发中遇到最难的问题以及如何解决,可以从以下几个关键点展开:
难点1:测试、部署和管理流程不熟悉。
你可以在项目中展示你的参与和成长。例如:我们项目使用了Maven进行项目管理、Jenkins进行部署,Git进行代码管理。筹码上滚源码除了编码,我还负责了单元测试和联调。我们最终将Java代码打包为jar包,并部署到了Linux服务器。这个过程展示你的项目测试、部署和管理的综合能力。
难点2:数据库性能调优经验。
你可以描述监控过程,如使用CAT、New Relic或Zabbix监控数据库。遇到性能问题时,通过查看执行计划和业务日志分析问题,例如,发现没有为特定字段建立索引或缓存,导致性能瓶颈。解决方法包括建立索引、使用复合索引或引入缓存。
难点3:JVM内存管理。
分享监控内存使用情况、处理内存泄露的经验,如通过JVM内存监控工具发现内存使用异常,并分析原因和采取的措施。例如,发现内存泄露是因为没有关闭文件对象或缓存设置不当,采取了关闭对象和优化缓存策略。
难点4:Linux操作系统技能。
分享在Linux环境下处理问题的经验,如在Linux服务器上查看日志文件,定位业务问题。描述遇到的错误,如服务器错误,并说明如何通过日志文件定位问题原因,并采取相应措施。
亮点5:理解底层源码。
分享通过阅读和理解底层源码解决实际问题的经验,例如在库存管理中遇到快速失效问题,通过阅读相关源码理解并解决。展示对数据结构和算法的理解能力。
在准备面试时,确保每个亮点都能结合具体项目经验进行阐述,并准备相关技能的细节,如数据库调优中的Redis和索引知识、JVM内存管理的JVM结构、算法与数据结构等,同时也要准备如何回答面试官可能提出的细节问题。面试过程中,通过引导面试官关注关键技能和经验,以展示你的项目经验和能力。
Java为什么可以在多个平台上运行
Java两种核心机制,第一个就是Java虚拟机(JVM)我们程序员编写源代码,也就是.java文件,然后必然要编译成.class文件,Java之所以是一次编译,到处运行,就是因为在运行的时候,Java虚拟机拿出.class里面代码来一行一行的解释,翻译给操作系统,因为操作系统本身是不认识Java的,是经过的虚拟机的翻译,一行一行的解释着执行,而且对于不同的操作系统平台,有不同的Java虚拟机,因此,Java才真正的实现了跨平台,一次编译,随处运行。
对于我们程序员这一端,是一样的,我们面对的就是.java和.class文件,程序要想执行,需要建立在操作系统环境之上,Java不是操作系统本地语言,Java又不是C,所以操作系统直接执行不了,那么在我们程序和操作系统的中间,打了一层Java虚拟机。ok?