2017-11-27 11 views
2

키 유형이 BitSet이고 값이 List 인 여러 맵을 직렬화하려고합니다. 현재 ~ 430k 개 요소가있는 8 개의지도가 있습니다. 각 키는 4096 비트를 포함하는 비트 세트입니다.Java에서 여러 개의 거대한 맵을 연속 처리하기

제 문제는 제작 된 파일의 크기에 있으며 프로 시저 자체에는 없습니다. 나는이에게 표준적인 방법 할 때마다 :

SerializationUtils.ensurePathExists(filePath); 
    DeflaterOutputStream fstream = new DeflaterOutputStream(new FileOutputStream(filePath.toFile())); 
    ObjectOutputStream ostream = new ObjectOutputStream(fstream); 
    ostream.writeObject(object); 
    ostream.close(); 

또는 Kryo하고 UnsafeOutput를 사용하여 - 나는 항상 크기 ~ 2백20메가바이트의 파일 끝을.

한편 python에서 똑같은 데이터 구조를 직렬화하면 (pickle 모듈을 사용하면) ~ 100MB 크기의 파일이 생성됩니다.

BitSet 클래스가 최적의 직렬화 루틴 (최소 정보량 작성)을 선언하는 것을 보았습니다. 내 유일한 추측은 여분의 ~ 100MB는 JVM 메타 오버 헤드의 일부에서 나온다는 것입니다. 여분의 100MB를자를 방법이 있습니까?

+0

@Eugene 그건 맞지 않아. 예를 들어 우리가 논의한 'serialVersionUId'값과 클래스 이름, 필드 이름과 타입 태그와 같은 메타 데이터가 생성됩니다. Object Serialization Speification의 Protocol 섹션을 참조하십시오. – EJP

+0

@Eugene 분명히 파이썬이하는 것보다 * 많이 * 더 많습니다. 당신은 둘 모두에 대해 추측하는 것 같습니다. – EJP

+0

@Eugene 음, 그러지 마세요. 너 혼란 스러울 뿐이야. 이 모든 것을 삭제하십시오. 간신히 하나의 정확한 단어를 게시했습니다. – EJP

답변

0

파이썬이하는 일에 대해 말할 수는 없지만 Java는 직렬화 된 스트림과의 호환성을 손상시키지 않으면 서 다양한 방법으로 클래스 정의를 변경할 수 있도록 많은 어려움을 겪고 있습니다. 예를 들어 필드는 클래스 정의의 순서에 의존하지 않고 이름과 유형과 함께 직렬화됩니다. 이 모든 것이 순차 화 프로토콜 오버 헤드를 추가합니다. BitSet이 최소한으로 직렬화되고 모든 JRE List 구현에 대해 동일하게 적용됩니다. 그러나 이는 List에있는 클래스에 적용되지 않을 수 있습니다.

대조적으로 인스턴스 객체에서 바이트를 직접 복사하는 직렬화 프로토콜을 생각할 수 있으며 직렬화와 비 직렬화간에 클래스가 전혀 변경되지 않아야합니다. 또는 유형을 직렬화하지만 이름은 직렬화하지 않습니다. 예를 들어, Java가 설계 목표를 달성하는 데 비해 공간을 절약 할 수 있습니다.