This research studies the characteristics of field usage patterns in the SpecJVM98 benchmarks. It finds that multiple object instances of the same class often exhibit different field-usage patterns. Motivated by this observation, we designed a heap compression mechanism that classifies object instances at runtime based on their field-usage patterns and eliminates unused fields to save space. To achieve the maximum space savings while minimizing the space and time overhead, our design combines three interrelated techniques in a novel manner: runtime object instance classification, field virtualization, and bidirectional object layout. An experimental evaluation reveals that this mechanism can reduce the maximum heap occupancy of SpecJVM98 benchmarks by up to 18% and 14% on average while keeping the application execution overhead low.