当前位置: 首页 > 面试题库 >

Java中零垃圾大字符串反序列化,庞大的对象问题

梁昊天
2023-03-14
问题内容

我正在寻找String一种byte[]在Java中反序列化a的方法,并尽可能减少产生的垃圾。因为我正在创建自己的序列化器和反序列化器,所以我拥有在服务器端(即序列化数据)和客户端(即反序列化数据)时实现任何解决方案的完全自由。

通过遍历char()并将每个(16位值)转换为2x 8位值,我设法有效地 序列化 了a
String而不产生任何垃圾开销。有这方面一个很好的辩论在这里。一种替代方法是使用反射直接访问基础,但这不在问题的范围之内。String's``String.charAt(i)``charString's``char[]

但是,对于我来说,如果byte[]不创建char[] 两次 ,似乎不可能反序列化,这似乎很奇怪。

步骤:

  1. 创造 char[]
  2. 遍历byte[]并填写char[]
  3. String(char[])构造函数创建字符串

由于Java的String不变性规则,构造函数复制char
[],从而产生2倍的GC开销。我总是可以使用机制来规避这一问题(不安全String分配+反射来设置char[]实例),但是我只想问一下是否有其他后果,除了打破关于String's不变性的所有约定。

当然,对此的最明智的回应是“继续,停止这样做并信任GC,原始文档char[]将非常短暂,而G1会立即删除它”,
如果char[]较小,这实际上是有道理的 超过G1区域大小的1/2 。如果更大,则char
[]将直接分配为巨大对象(即自动传播到G1区域之外)。很难有效地将这些对象收集到G1中。这就是每个分配都很重要的原因。

有关如何解决此问题的任何想法?

非常感谢。


问题答案:

我发现一个解决方案,如果您具有不受管理的环境,那将是无用的。

java.lang.String类有一个包私有构造String(char[] value, boolean share)

资源:

/*
* Package private constructor which shares value array for speed.
* this constructor is always expected to be called with share==true.
* a separate constructor is needed because we already have a public
* String(char[]) constructor that makes a copy of the given char[].
*/
String(char[] value, boolean share) {
    // assert share : "unshared not supported";
    this.value = value;
}

这是正在在Java中广泛使用,例如Integer.toString()Long.toString()String.concat(String)String.replace(char,char)String.valueOf(char)

解决方案(或破解,无论您想调用什么)是将类移至java.lang包并访问包私有的构造函数。这对于安全管理器来说不是一个好兆头,但是可以绕开它。



 类似资料:
  • 我正在寻找一种方法,在Java中从反序列化,并尽可能少地产生垃圾。因为我正在创建自己的序列化程序和反序列化程序,所以我可以完全自由地在服务器端(即序列化数据时)和客户端(即反序列化数据时)实现任何解决方案。 我已经设法通过遍历字符()并将每个(16位值)转换为2x 8位值,从而有效地序列化了,而不会产生任何垃圾开销。这里有一个很好的争论。另一种选择是使用反射直接访问底层,但这超出了问题的范围。 然

  • [GC(分配失败)[defnew:10931K->472K(12288K),0.0053905秒]10931K->10712K(39616K),0.0054285秒][times:user=0.00 sys=0.00,real=0.01秒] [GC(分配失败)[defnew:10712k->472k(12288k),0.0057686秒]20952k->20952k(39616k),0.00580

  • 我尝试从一个用于存储Spring会话的Redis服务器反序列化String到Java对象,并且我想在Spring框架之外反序列化它。我认为Spring Redis序列化器可能使用默认字符集UTF-8来将Java对象序列化为字符串。 Redis中的字符串: 错误消息: 我知道用UTF-8在Byte[]和String之间的转换很可能是问题所在,但我还是想问一下,是否有人知道如何在不修改序列化部分的情况

  • 问题内容: 我有以下字符串 我想反序列化一个类的对象 我正在使用python 2.6和2.7 问题答案:

  • 问题内容: 我正在阅读有关垃圾收集的信息,当我搜索字符串文字垃圾收集时,搜索结果令人困惑。 我需要澄清以下几点: 如果在编译时将字符串定义为文字字符串,那么是否会对其进行垃圾回收? 如果使用实习方法,那么它会被垃圾回收吗?在第1点中,它也将与文字区别对待。 有人提到只有在卸载类时才会对文字进行垃圾回收吗?是否有道理,因为我认为永远不会卸课。 问题答案: 如果在编译时将字符串定义为文字字符串,那么是

  • java对象:MyObject有antherObject1的列表,antherObject1也有antherObject2的列表 json字符串:这是我的JSON字符串,通过它我想使用对象映射器创建一个java对象 ObjectMapper代码//将字符串转换为响应对象 例外:这里是例外 请指导我如何使它成为可能。