似乎ByteBuffer
将创建一个新的字节数组,因此有一个额外的内存副本。我可以直接将字符串编码为void putString(ByteBuffer bb, String s) {
byte[] arr = s.getBytes(StandardCharsets.UTF_8);
bb.put(arr);
}
而没有中间字节数组吗?
例如:
add_filter( $filter_name, array( __CLASS__, 'filter_value_save' ), PHP_INT_MIN, 1 );
add_filter( $filter_name, array( __CLASS__, 'filter_value_restore' ), PHP_INT_MAX, 1 );
return true;
}
public static function remove_filter_protection( $filter_name ) {
if ( ! has_filter( $filter_name, array( __CLASS__, 'filter_value_restore' ) ) ) {
return false;
}
remove_filter( $filter_name, array( __CLASS__, 'filter_value_save' ), PHP_INT_MIN );
remove_filter( $filter_name, array( __CLASS__, 'filter_value_restore' ), PHP_INT_MAX );
这段代码将创建一个字节数组,将字符串编码为此字节数组,然后将字节数组的内容复制到ByteBuffer。 我认为字节数组不是必需的,它会带来GC和额外的内存复制。
答案 0 :(得分:2)
您可以使用CharsetEncoder
直接写入ByteBuffer
:
static void putString(ByteBuffer buffer, String str, Charset charset) {
CharsetEncoder encoder = charset.newEncoder();
encoder.encode(CharBuffer.wrap(str), buffer, true);
encoder.flush(buffer);
}
您有责任确保分配足够的空间。您还可以检查encode()
方法的结果,看看它是否成功。
答案 1 :(得分:1)
我无法想到一种完全消除中间字节数组的简单方法。
但是如果你因为字符串很大而担心这个问题,你可以把它分成几块:
for(offset=0; offset<str.length(); offset+=chunkSize) {
String chunk = str.substring(offset, offset+chunkSize);
byteBuffer.put(chunk.getBytes(StandardCharsets.UTF_8));
}
但是,如果您的输入字符串足够大以至于需要进行此优化,那么您的程序的整体架构可能是错误的。
除非您在分析时看到异常情况,否则不担心GC性能。在高效的GC中,JRE是辉煌的。
答案 2 :(得分:0)
不,这是不可能的。字符串对象没有编码。
答案 3 :(得分:0)
String对象按目的是不可变的。该类的整个想法是不允许操纵任何底层数据结构(主要是出于安全性和性能优化的原因)。
从这个意义上说:没有其他更好的方法来获取构成Java中字符串对象的字节。