java - 请求已超过允许的时间限制和 Java Heap Space Null 错误

标签 java mysql coldfusion jvm

我知道这个话题似乎被讨论过很多次,但是我已经尝试了所有提到的方法都无济于事。

我不断收到错误:

The request has exceeded the allowable time limit Tag: CFQUERY
The error occurred on line 152.

还有

Java heap space null
The error occurred on line -1.

在同一个 html 页面上。

我认为 Java 堆空间错误导致超时,反之亦然。

发生超时的程序是

        <CFQUERY DATASOURCE="#datasource#" USERNAME="#username#" PASSWORD="#password#" NAME="myQuery" CACHEDWITHIN="#CreateTimeSpan(0,0,5,0)#">
    SELECT tableA.productid, tableA.userid, tableA.salesid, tableA.productname, tableA.price, tableA.units, tableA.currency, tableA.terms, tableA.description, tableA.pic, tableA.minorder, tableA.salesid, tableB.id, tableB.company, tableB.city, tableB.state, tableB.country, tableB.contact, tableB.skype
    FROM tableA LEFT OUTER JOIN tableB
    ON tableA.userid = tableB.userid
        WHERE tableA.category = <cfqueryparam value = "#cat#" cfsqltype = "cf_sql_integer" maxLength = "2">
        ORDER by tableA.ranks DESC
        </CFQUERY>

我不知道如何进一步“优化”它?它只检索了大约 28,000 条结果记录,不是 200 万条。我正在使用 MySQL 数据库。

我已将我的 MaxPermSize 从 256MB 增加到 512MB,但问题似乎仍然存在,尤其是当搜索引擎进入站点进行索引时。我在具有 6GB RAM 的服务器上运行 CF9。以下是我在 CF 中的一些设置:

  • 最小和最大 JVM 堆大小都设置为 512MB。
  • (秒)后的超时请求设置为 60
  • JVM 版本 1.7.0_67
  • JVM 参数:

    -server -Dsun.io.useCanonCaches=false -XX:-UseGCOverheadLimit -XX:MaxPermSize=512m -XX:+UseParallelGC -Xbatch -Dcoldfusion.rootDir={application.home}/../ -Dcoldfusion.libPath={application.home}/../lib

欢迎任何建议。提前致谢。

附加信息:

  1. 有26类产品
  2. 每个类别有 20-50K 条记录,并且每天都在增加
  3. 人们可能会或可能不会在一天中的不同时间访问所有 26 个不同的类别
  4. 并非所有类别都每天更新,但有些类别是

最佳答案

每个类别有 20-40k 个产品,20 个类别,行大小未知,您需要对数据缓存做出一些真正的架构决策(如果您确实使用缓存)。目前,每个类别 id 参数将是该查询的唯一缓存,其生存时间为五分钟,会消耗一些堆空间。此外,它必须在请求期间从缓存中复制出来,并且会消耗内存直到它被收集。另请注意,permgen 与堆大小无关。

我建议不要缓存以查看数据库服务器如何通过仅请求该页面的记录来处理它。内置查询缓存是非常有情境的,这不是其中一种情况。 30k 条记录可能看起来并不多,直到您意识到您有产品描述和其他每个半兆的大文本 block 。如果您可以为任何具有强大目录的典型商业站点提供服务,我强烈建议您至少使用一两个堆。 (你说“我在一台有 6GB RAM 的服务器上运行 CF9。”希望其中一些可以免费分配给 JVM)。在这种情况下,更多的内存只会将问题推迟到以后,如果有的话。

此外,将 permgen 拉回 256。512 permgen 相当高,即使对于大型企业应用程序也是如此。

这是收到请求时您的应用当前的运行方式。

  1. 命中查询标签并返回结果
    1. 缓存命中 - 结果从缓存中复制出来,浪费了一些兆字节
    2. 缓存未命中——结果从数据库中流入,占用了一些浪费的兆字节,并额外复制到缓存区域(但你避免了数据库加载时间和传输时间,我怀疑你的大部分时间都花在了传输而不是查询)
  2. 您使用了一小部分查询
  3. 查询已被垃圾回收

在轻负载下,您的服务器可能几乎无法跟上。谁知道您的缓存区域能够避免流失的频率。

额外跟进:

听起来您所做的所有这些只是为了分页的行数。实际上,您可以将总行数放入仅返回一页记录的查询中作为子查询。如果您想分成两个查询——一个查询行数,一个查询该行的记录,那么前者是缓存的一个很好的竞争者。它是不会经常变化的数据,如果变化了,稍微落后一点也没关系。此外,它非常小,实际上缓存而不是一直询问数据库是有意义的。

关于java - 请求已超过允许的时间限制和 Java Heap Space Null 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39966560/

相关文章:

coldfusion - COLDFUSION BUILDER 是否支持 Coldfusion 8?

Java BitTorrent 库

java - Log4j 2 : How to add references from my classes in my log4j. 属性

mysql - 使用 Rails 应用程序中存在于多个数据库中的表

php - 在 Div 容器中显示 JSON 字符串

coldfusion - mxunit 测试用例中的函数执行顺序

java - 泛型 - 正确处理原始类型警告 :

java - 如何将 'jump' 发送到 Java 中的方法而不链接回调用它的位置?

php - 如何创建逗号分隔的单词

coldfusion - 如何从 ColdFusion 9 中的单独应用程序访问一个应用程序范围?