Skip to main content

June 2019

关于JVM内存泄漏之GC优化问题提出

Submitted by taotao on Fri, 06/28/2019 - 12:14

概述

根据上一篇文章,将JVM升级到212版本,并追加设置了-Xmx和-Xms参数之后,生产环境的JVM内存一直维持在300-800M之间,高负载和低负载的实例,内存开销都在这个范围之内。所以从这两天的线上验证的现象来看是符合预期的,证实了之前的猜测是正确的(之前的结论参考:JVM的内存泄漏调查)。

详细分析

下面我将结合听云监控上的数据进行分析和论证。

下图是内存开销,可以看出内存开销在500M范围以下。

tingyun_memory_size

下面是Eden区域的内存开销,可以看出eden区大小在250M之内。

JVM的内存泄漏调查

Submitted by taotao on Wed, 06/26/2019 - 19:18

概述

        最近这半个月生产环境的服务出现了一个比较奇怪的现象,相同的一个服务,有两个实例,其中一个实例的负载比较高,RPM有500-1000左右,另一个实例的RPM在20-50之间,其中低负载的实例吃的内存比较多,能吃到8G左右的内存,另一个高负载的实例,内存稳定维持在2-3个G,吃内存比较高的那个服务,运维在日常巡检的时候发现会手动重启一次服务,避免服务出现OOM的问题。因为这个问题比较频繁,所以反馈到研发这边。这个问题的经过分析定位,排除日志堆积的问题、排除是听云探针的问题之后,把原因定位在了JVM内存自动增长导致的问题,因为根据监控平台上可以看到GC的回收频次很低,因为一旦JVM可用的内存不够,如果没有设置最大可用内存,那么JVM就会自动增长,而自动增长内存后,就不会达到GC触发的条件,这样就导致内存一直增长,而没有垃圾回收的问题。

详细的分析过程

         首先让运维通过利用jmap的方式将JVM的内存信息dump出来,

jmap -dump:format=b,file=文件名.dump 进程id 

经过分析发现了听云的对象占用了大概20%左右的内存空间:

Maven中的pluginManagement的问题

Submitted by taotao on Tue, 06/11/2019 - 12:16

概述

          在最近的一个maven多模块项目中,B module依赖了A module中的一个类,用如下命令打包的时候

mvn clean install

遇到错误:

maven cannot find symbol class Person

经过一番的调查,发现是由于在父工程的POM文件缺少pluginManagement节点引起的问题。下面是问题的具体分析过程。

详细介绍

在碰到这个问题的时候,第一直觉是和maven的module机制有关系,因为工程可以在idea里正常启动。 判断应该是自己对于maven模块机制的一些知识欠缺,于是在maven官网上学习了一下关于多模块工程的知识,其中有如下的收获:

Tags

不要使用CascadeType.ALL

Submitted by taotao on Sat, 06/08/2019 - 18:16

概述

         在使用Hibernate级连设置的时候,我们可以设置CascadeType.ALL, 这样如果删除了父对象,就会导致相关的子对象也会被删除。而如果子对象是可以独立存在,那么就不能被删除,本文主要介绍设置了CascadeType.ALL之后,父子对象被级连删除的详细情况和应该如何设置级连属性。

详细介绍

         假设我们有一个Student实体和一个Course实体,一个学生会选修多个课程,一个课程可能会被多个学生选择,所以我们这里就可以有如下的实体定义:

Tags

如何在Hibernate中转义SQL中的关键字

Submitted by taotao on Mon, 06/03/2019 - 17:49

概述

        我们在实际的项目中,可能会将一些SQL的关键字作为实体的属性名,我们可能会使用如下的数据库:MySQL 、PostgreSQL 、SqlServer,每个数据库都有各自不同的保留关键字,因此如果我们要将这些关键字作为实体属性的名称,或者数据库的表名,数据库就会报错。如何解决这个问题?我们可以用如下的两个方法。

在实体定义的时候通过 标注的方式指定

我们如果有如下的实体定义

Tags

Hibernate中的实体状态切换

Submitted by taotao on Sun, 06/02/2019 - 16:24

概述

        我们在使用ORM工具时,直接和实体进行交互,就可以操作数据库,不再需要写 SQL语句。但是Hibernate不是软件饮弹,我们还是需要关注它生成出来SQL。那么在一次操作的过程中实体会经历哪些状态?各个状态又有哪些含义和作用?

详细解释

Transient

         一个对象刚创建时的状态,这个状态下的对象还没有映射为数据库中的记录。只有调用Session.save()或者 EntityManager.persist()方法的时候,状态会切换为Managed。

Managed

          刚创建的对象通过调用Session.save()或者EntityManager.persist()方法的时候,就会从 Transient状态切换到Managed状态,该状态下的对象的任何属性值改变都会在Session.flush()的时候,自动同步到数据库中,因此我们不需要手动执行insert/update/delete这些方法。

Tags