-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
在bot.sendMsg()方法中构建img传递base64图片时特定图片会发生oom异常 #242
Comments
@MisakaTAT @Hyperionml final void ensureCapacity(int minCapacity) {
if (minCapacity - this.chars.length > 0) {
int oldCapacity = this.chars.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
if (newCapacity - this.maxArraySize > 0) {
throw new OutOfMemoryError("try enabling LargeObject feature instead");
}
this.chars = Arrays.copyOf(this.chars, newCapacity);
}
} 其中使用成员变量 public class FastJson2Demo {
/**
* 字符集
*/
private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
/**
* 字符串长度,此处减去1M的字符
*/
private static final long STRING_LENGTH = 64L * 1024L * 1024L - (1024L * 1024L);
public static void main(String[] args) {
JSONObject jsonObject = new JSONObject();
// 生成64 * 1024 * 1024长度的字符串
Random random = new Random();
StringBuilder largeStringBuilder = new StringBuilder();
for (long i = 0; i < STRING_LENGTH; i++) {
int index = random.nextInt(CHARACTERS.length());
largeStringBuilder.append(CHARACTERS.charAt(index));
}
String largeString = largeStringBuilder.toString();
System.out.println("Generated string length: " + largeString.length());
System.out.println("UTF-8 Bytes length: " + largeString.getBytes(StandardCharsets.UTF_8).length);
System.out.println("UTF-8 Bytes quotient: " + largeString.getBytes(StandardCharsets.UTF_8).length / (1024L * 1024L));
System.out.println("UTF-8 Bytes remainder: " + largeString.getBytes(StandardCharsets.UTF_8).length % (1024L * 1024L));
System.out.println("UTF-16 Bytes length: " + largeString.getBytes(StandardCharsets.UTF_16).length);
System.out.println("UTF-16 Bytes quotient: " + largeString.getBytes(StandardCharsets.UTF_16).length / (1024L * 1024L));
System.out.println("UTF-16 Bytes remainder: " + largeString.getBytes(StandardCharsets.UTF_16).length % (1024L * 1024L));
jsonObject.put("largeString", largeString);
String jsonString = jsonObject.toJSONString();
System.out.println("Generated JSON string length: " + jsonString.length());
System.out.println("Generated JSON string: " + jsonString);
}
} 执行上述代码,控制台打印为:
我们可以看到,即使我为生成JSON字符串时会拼接的字符预留了1M的长度,其依然发生了 |
@ElksZero 很好,就是下次码字速度需要再快一些( |
我之前的描述是错误的,我的Demo案例中所发生的异常与字符编码无关。Demo中实际导致发生异常的原因为FastJson2的扩容方法的问题。 final void ensureCapacity(int minCapacity) {
if (minCapacity - this.chars.length > 0) {
int oldCapacity = this.chars.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
if (newCapacity - this.maxArraySize > 0) {
throw new OutOfMemoryError("try enabling LargeObject feature instead");
}
this.chars = Arrays.copyOf(this.chars, newCapacity);
}
} 如上代码中包含 |
详细描述
利用如下方法发送图片时
其中img为正确格式的base64字符串,在发送图片时遇到oom异常
但是经过多测尝试不同的图片,改异常只会发生在部分图片中,且发生错误的图片会稳定触发异常,且触发异常的图片并无相同点(也可能是我没发现)
预期结果
正常的发送图片信息
当前结果
在发送部分图片时稳定触发oom异常
在最新的RELEASE版本中能否复现?
是(由于maven仓库中最高版本为2.3.1,所以使用的是2.3.1)
复现方法
使用上面提到的发送图片的方法
本人使用如下方法将网络url转换为base64,且该过程中并未出现过oom异常
将图中的url替换成以下url即可稳定触发oom,3长图片的内存大小分别是 5.3m 13.4m 6.7m
https://i.pixiv.re/img-original/img/2022/11/29/21/02/54/103201474_p0.jpg
https://i.pixiv.re/img-original/img/2023/05/13/00/10/06/108069486_p0.png
https://i.pixiv.re/img-original/img/2022/03/29/20/43/59/97262943_p0.jpg
屏幕截图或者日志
根据我的打点深入,oom发生在如图所在的位置,即payload.toJSONString(new JSONWriter.Feature[0]);方法中
运行或开发环境
The text was updated successfully, but these errors were encountered: