Too many constants, the constant pool for ***_jsp would exceed 65536 entries

最近在给公司处理报告生成的相关业务(就是从数据库取数据、通过jsp生成html页面)。由于业务中数据量较大,又涉及大量货币、时间、日期等的格式化显示以及空数据等各种情况的判断,起初将这些判断大部分放在jsp页面中用jstl以及el表达式完成,这导致了jsp页面的逻辑过于复杂。

我们都知道jsp解析的最终结果也将是一个class,由于上面说过,我将大量逻辑放在了jsp页面上,这就导致了jsp编译结果(class)过于庞大,以至于触碰到了java虚拟机(JVM)对单个类(或接口)的最大限制(65536)。程序抛出异常:“Too many constants, the constant pool for ***_jsp would exceed 65536 entries”

至于这个限制是怎么回事,涉及到java虚拟机的运行机制,本人也不甚清楚,但一番搜索后,高人给出了如下解释:


(1)OutSystems上高人给出如下解释:(http://www.outsystems.com/forums/discussion/14233/too-many-constants-the-constant-pool-for-mypage-jsf-exceed-65536-entries/#Post52718)
(a)
Tiago Neves: 

João,
The limit you reached is related with the constants per class, limited by the 16-bit constant pool.
The exact limitation as per official documentation is:
The per-class or per-interface constant pool is limited to 65535 entries by the 16-bit constant_pool_count field of the ClassFile structure (§4.1). This acts as an internal limit on the total complexity of a single class or interface.

You can read more on class limitations here:
https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.11


(b)
Luís Lopes:

Hi all, as pointed out, this is a JVM limitation if you write too many code in a single class.
You've guys already nailed the technical details and found out what is happening, but I'll confirm some of the doubts.
 
The error suggests that the error occurred while trying to compile the jsp for the page.
JSP pages are compiled and generate roughly 1 method per widget, our widgets have a 1-1 match to the jsp widgets.
I can only assume that your webpage has a lot of controls.
 
For the error that Michael Deroche reproduced:
"[javac] Too many methods for type ScrnWebScreen1. Maximum is 65535"
 
This is the Java bean code-behind for the page. 
There is 1 class per Screen / Block, and each widget roughly generates about 3-6 methods, depending on the widget and its properties.
This explains why it still crashes with 30k containers.
 
Hope this clarified some of the doubts about the internals. 
 
To the original poster, if this is impacting you, as said previously
you should contact support, so we can give you advice, doing an analysis on your application.

Best Regards


(2)IBM support对该问题也做回避处理:(http://www-01.ibm.com/support/docview.wss?uid=swg1PM96400)

"There is no plan to fix the "Too many constants" since it's caused by a limitation of the JRE."


(3)Oracle的JVM Specification 给出了如下解释:(https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.11)

4.11. Limitations of the Java Virtual Machine

The following limitations of the Java Virtual Machine are implicit in the class file format:


The per-class or per-interface constant pool is limited to 65535 entries by the 16-bit constant_pool_count field of the ClassFile structure (§4.1). This acts as an internal limit on the total complexity of a single class or interface.


The number of fields that may be declared by a class or interface is limited to 65535 by the size of the fields_count item of the ClassFile structure (§4.1).


Note that the value of the fields_count item of the ClassFile structure does not include fields that are inherited from superclasses or superinterfaces.


The number of methods that may be declared by a class or interface is limited to 65535 by the size of the methods_count item of the ClassFile structure (§4.1).


Note that the value of the methods_count item of the ClassFile structure does not include methods that are inherited from superclasses or superinterfaces.


The number of direct superinterfaces of a class or interface is limited to 65535 by the size of the interfaces_count item of the ClassFile structure (§4.1).


The greatest number of local variables in the local variables array of a frame created upon invocation of a method (§2.6) is limited to 65535 by the size of the max_locals item of the Code attribute (§4.7.3) giving the code of the method, and by the 16-bit local variable indexing of the Java Virtual Machine instruction set.


Note that values of type long and double are each considered to reserve two local variables and contribute two units toward the max_locals value, so use of local variables of those types further reduces this limit.



The size of an operand stack in a frame (§2.6) is limited to 65535 values by the max_stack field of the Code attribute (§4.7.3).


Note that values of type long and double are each considered to contribute two units toward the max_stack value, so use of values of these types on the operand stack further reduces this limit.



The number of method parameters is limited to 255 by the definition of a method descriptor (§4.3.3), where the limit includes one unit for this in the case of instance or interface method invocations.


Note that a method descriptor is defined in terms of a notion of method parameter length in which a parameter of type long or double contributes two units to the length, so parameters of these types further reduce the limit.



The length of field and method names, field and method descriptors, and other constant string values (including those referenced by ConstantValue (§4.7.2) attributes) is limited to 65535 characters by the 16-bit unsigned length item of the CONSTANT_Utf8_info structure (§4.4.7).


Note that the limit is on the number of bytes in the encoding and not on the number of encoded characters. UTF-8 encodes some characters using two or three bytes. Thus, strings incorporating multibyte characters are further constrained.


The number of dimensions in an array is limited to 255 by the size of the dimensions opcode of the multianewarray instruction and by the constraints imposed on the multianewarray, anewarray, and newarray instructions (§4.9.1, §4.9.2).


解决方案:

目前来看没有很好的解决方案。


替代方案:

(1)对类(或接口)进行拆分,分成更小的业务类。

(2)对jsp页面进行拆分,将大型的jsp页面拆分成较小的jsp页面显示。

(3)尽量减少jsp页面的逻辑复杂程度,jsp只负责展示数据,数据逻辑尽量放到后台完成(如:货币、时间、日期等数据而定格式化)。

(4)采用以下方式组织模块:“<jsp:include flush="true" page="***.jsp" />” (将整个jsp页面,拆成多个模块,以include引入的方式将这些模块组织在某个jsp里)


原文:http://blog.csdn.net/tomorrow13210073213/article/details/50669214


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值