JSON Builder导致Tomcat8应用程序中的内存泄漏 [英] JSON Builder cause memory leak in Tomcat8 Application

查看:125
本文介绍了JSON Builder导致Tomcat8应用程序中的内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经为Tomcat8服务器创建了WebApp.这是一款基于网络的小型游戏.

I've created a WebApp for a Tomcat8 Server. It is a small webbased game.

由于我已从平面文件切换到MySQL,因此javax.json构建器存在很多问题.

Since I've switched from flatfiles to MySQL I have a lot of problems with javax.json builder.

这是我的代码的一部分:

Here the part of my code:

public void saveUserResearch(){
    MySQLTable t = SpaceWar.instance().getUserResearchTable();

    JsonObjectBuilder mainBuilder = Json.createObjectBuilder();
    JsonObjectBuilder subBuilder = Json.createObjectBuilder();
    for(UserResearch r : getResearchList()){
        int index = r.getIndex();
        subBuilder = Json.createObjectBuilder();
        subBuilder.add("index", r.getIndex());
        subBuilder.add("level", r.getLevel());
        subBuilder.add("planed_level", r.getPlanedLevel());
        subBuilder.add("player_uuid", r.getPlayerUUIDAsString());
        subBuilder.add("unlocked", r.getUnlocked());
        subBuilder.add("savedInPlayer", "yes");
        mainBuilder.add(index+"", subBuilder.build());
    }
    String q = "";
    q += "user_uuid:" + getUUID().toString() + ";";
    q += "research_json:" + mainBuilder.build();
    t.insertUpdate(q).sync();

}

Maven依赖项:

<!-- https://mvnrepository.com/artifact/javax.json/javax.json-api -->
        <dependency>
            <groupId>javax.json</groupId>
            <artifactId>javax.json-api</artifactId>
            <version>1.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.glassfish/javax.json -->
        <dependency>
            <groupId>org.glassfish</groupId>
            <artifactId>javax.json</artifactId>
            <version>1.0.4</version>
        </dependency>

我每2分钟从一个线程调用一次此方法.我在游戏中有15位用户,因此它运行了15次.它创建一个JSON对象,并将我要保存到JSON DB的JSON对象.因此,我希望有15个实例.

This method I am calling from a Thread every 2 minutes. I have 15 users in the game, so it runs 15 times. It creates a JSON Object and the JSON object I am saving to a MySQL DB. So I am expecting 15 instances.

问题是几个小时后,Tomcat服务器崩溃并显示以下消息.

The problem is after a few hours, the Tomcat Server crashes with following message.

Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000007b5400000, 1048576, 0) failed; error='Cannot allocate memory' (errno=12)

 There is insufficient memory for the Java Runtime Environment to continue.
 Native memory allocation (mmap) failed to map 1048576 bytes for committing reserved memory.
 An error report file with more information is saved as:
 /tmp/hs_err_pid11069.log

因此,我决定使用VisualVM对其进行研究,在那里我发现了很多麻烦.

So I decided to use VisualVM to take a look into it and there I've found a lot of trouble.

在第一张图片中,您可以看到存在相同的用户json对象.

In the first image you can see that there are the same user json object.

因此,我尝试将mainBuilder和subBuilder设置为null.但结果相同.我也尝试调用System.gc();.但这并不能清除所有内容.

So I tried to set the mainBuilder and subBuilder to null. But with the same result. Also I tried to call System.gc(); but it does not clear the stuff.

2小时后看起来像这样

After 2h it looks like this

大约5个小时后,它的内存不足了

And after about 5 hours it runs out of memory

这些是我的JVM参数

These are my JVM Arguments

我不确定为什么构建器会导致这种内存泄漏,而我的知识还不足以解决它.也许你可以帮我.

I am not sure why the builder cause this kind of memory leak and my knowledge is not great enough to solve it. Maybe you can help me.

我将非常感谢.非常感谢.

I would be very grateful. Thank you very much.

对于MySQL,我在这里使用API​​: SpiderMySQL 还有javax.json.Json; javax.json.JsonObjectBuilder;

For the MySQL stuff I am using an API from here: SpiderMySQL And the javax.json.Json; javax.json.JsonObjectBuilder;

推荐答案

我认为我发现了问题.它是mysql lib! 在这里查看课程: https://gitlab.com/Syranda/SpiderMySQL/blob/development/src/main/java/de/syranda/spidermysql/WatchThread.java

I think i found the issue. It is the mysql lib! look at the class here: https://gitlab.com/Syranda/SpiderMySQL/blob/development/src/main/java/de/syranda/spidermysql/WatchThread.java

它不是线程安全的,因为ArrayList不是线程安全的.他们已经有一张臭虫票了.

It is not thread safe, since ArrayList is not thread safe. They have already a bug ticket for this.

结合此类: https://gitlab.com/Syranda/SpiderMySQL/blob/development/src/main/java/de/syranda/spidermysql/table/InsertQuery.java

它使 this 引用在构造函数中转义.在多线程环境中,这是非常邪恶的.它会产生奇怪的行为,甚至可能导致您的内存泄漏.

It lets the this reference escape in the consturctor. Which is very evil in multithreaded environments. It can produce strange behavior and maybe your memory leak.

在这种情况下,您可以尝试切换到纯jdbc,只是为了测试内存泄漏是否仍然存在.而且我建议使用任何其他lib,看来执行起来不太好.

you can try to switch to pure jdbc in that case just to test if the memory leak stays. And i recommend to use any other lib, it seems not to be implemented really well.

我测试了JSON impl,它没有没有内存泄漏

I tested the JSON impl, it has no memory leak

这篇关于JSON Builder导致Tomcat8应用程序中的内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆